From 41c698bf760cca5636b856d9fc4c8ef8c90c3358 Mon Sep 17 00:00:00 2001 From: glenn schrooyen Date: Fri, 12 Sep 2025 23:29:12 +0200 Subject: [PATCH] Update CI workflows to utilize self-hosted runners with specific labels for API Docs, API Gateway, Service Adapters, Frontend, and Integration Tests; enhance progress documentation to reflect changes in runner configurations --- .env.runners | 3 + .gitea/workflows/api-docs.yml | 4 +- .gitea/workflows/api-gateway.yml | 6 +- .gitea/workflows/ci.yml | 12 +- .gitea/workflows/frontend.yml | 6 +- .gitea/workflows/integration-tests.yml | 2 +- .gitea/workflows/service-adapters.yml | 4 +- docker-compose.runners.yml | 142 +++++++++++ docs/RUNNERS.md | 312 +++++++++++++++++++++++++ docs/progress.md | 2 + docs/structure.txt | 10 +- env.runners.example | 14 ++ scripts/manage-runners.ps1 | 208 +++++++++++++++++ scripts/manage-runners.sh | 209 +++++++++++++++++ 14 files changed, 916 insertions(+), 18 deletions(-) create mode 100644 .env.runners create mode 100644 docker-compose.runners.yml create mode 100644 docs/RUNNERS.md create mode 100644 env.runners.example create mode 100644 scripts/manage-runners.ps1 create mode 100644 scripts/manage-runners.sh diff --git a/.env.runners b/.env.runners new file mode 100644 index 0000000..404260b --- /dev/null +++ b/.env.runners @@ -0,0 +1,3 @@ +# Gitea Runners Environment Configuration +GITEA_INSTANCE_URL=http://localhost:3000 +GITEA_RUNNER_TOKEN=your_runner_registration_token_here diff --git a/.gitea/workflows/api-docs.yml b/.gitea/workflows/api-docs.yml index 76ed491..21d5842 100644 --- a/.gitea/workflows/api-docs.yml +++ b/.gitea/workflows/api-docs.yml @@ -16,7 +16,7 @@ env: jobs: test: - runs-on: ubuntu-latest + runs-on: [self-hosted, light, nodejs] defaults: run: working-directory: ./services/api-docs @@ -113,7 +113,7 @@ jobs: echo "Jest test results: services/api-docs/test-results/" build: - runs-on: ubuntu-latest + runs-on: [self-hosted, light, nodejs] needs: test defaults: run: diff --git a/.gitea/workflows/api-gateway.yml b/.gitea/workflows/api-gateway.yml index b50c9fb..4f17f07 100644 --- a/.gitea/workflows/api-gateway.yml +++ b/.gitea/workflows/api-gateway.yml @@ -16,7 +16,7 @@ env: jobs: test: - runs-on: ubuntu-latest + runs-on: [self-hosted, heavy, java] defaults: run: working-directory: ./services/api-gateway @@ -82,7 +82,7 @@ jobs: name: api-gateway-coverage build: - runs-on: ubuntu-latest + runs-on: [self-hosted, heavy, java] needs: test defaults: run: @@ -116,7 +116,7 @@ jobs: run: docker build -t api-gateway:test . security: - runs-on: ubuntu-latest + runs-on: [self-hosted, security, scan] needs: build steps: diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index be54628..44653bb 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -13,7 +13,7 @@ env: jobs: # Java Spring Boot API Gateway api-gateway: - runs-on: ubuntu-latest + runs-on: [self-hosted, heavy, java] defaults: run: working-directory: ./services/api-gateway @@ -49,7 +49,7 @@ jobs: # Python FastAPI Service Adapters service-adapters: - runs-on: ubuntu-latest + runs-on: [self-hosted, heavy, python] defaults: run: working-directory: ./services/service-adapters @@ -99,7 +99,7 @@ jobs: # Node.js API Documentation Service api-docs: - runs-on: ubuntu-latest + runs-on: [self-hosted, light, nodejs] defaults: run: working-directory: ./services/api-docs @@ -144,7 +144,7 @@ jobs: # React Frontend frontend: - runs-on: ubuntu-latest + runs-on: [self-hosted, light, frontend] defaults: run: working-directory: ./frontend @@ -189,7 +189,7 @@ jobs: # Integration Tests integration-tests: - runs-on: ubuntu-latest + runs-on: [self-hosted, docker, integration] needs: [api-gateway, service-adapters, api-docs, frontend] steps: @@ -224,7 +224,7 @@ jobs: # Security and Quality Gates security-scan: - runs-on: ubuntu-latest + runs-on: [self-hosted, security, scan] needs: [api-gateway, service-adapters, api-docs, frontend] steps: diff --git a/.gitea/workflows/frontend.yml b/.gitea/workflows/frontend.yml index 07a2288..ef582d1 100644 --- a/.gitea/workflows/frontend.yml +++ b/.gitea/workflows/frontend.yml @@ -16,7 +16,7 @@ env: jobs: test: - runs-on: ubuntu-latest + runs-on: [self-hosted, light, frontend] defaults: run: working-directory: ./frontend @@ -85,7 +85,7 @@ jobs: echo "Jest test results: frontend/test-results/" build: - runs-on: ubuntu-latest + runs-on: [self-hosted, light, frontend] needs: test defaults: run: @@ -131,7 +131,7 @@ jobs: run: docker build -t frontend:test . lighthouse: - runs-on: ubuntu-latest + runs-on: [self-hosted, light, frontend] needs: build if: github.event_name == 'pull_request' diff --git a/.gitea/workflows/integration-tests.yml b/.gitea/workflows/integration-tests.yml index 806da17..1a92ba0 100644 --- a/.gitea/workflows/integration-tests.yml +++ b/.gitea/workflows/integration-tests.yml @@ -12,7 +12,7 @@ env: jobs: integration-tests: - runs-on: ubuntu-latest + runs-on: [self-hosted, docker, integration] services: postgres: diff --git a/.gitea/workflows/service-adapters.yml b/.gitea/workflows/service-adapters.yml index 941c208..ba86f74 100644 --- a/.gitea/workflows/service-adapters.yml +++ b/.gitea/workflows/service-adapters.yml @@ -16,7 +16,7 @@ env: jobs: test: - runs-on: ubuntu-latest + runs-on: [self-hosted, heavy, python] defaults: run: working-directory: ./services/service-adapters @@ -99,7 +99,7 @@ jobs: echo "Security reports: bandit-report.json, safety-report.json" build: - runs-on: ubuntu-latest + runs-on: [self-hosted, heavy, python] needs: test defaults: run: diff --git a/docker-compose.runners.yml b/docker-compose.runners.yml new file mode 100644 index 0000000..d9b1a98 --- /dev/null +++ b/docker-compose.runners.yml @@ -0,0 +1,142 @@ +version: '3.8' + +services: + # Runner 1: Heavy workloads (Java/Python) + gitea-runner-heavy: + image: gitea/act_runner:latest + container_name: labfusion-runner-heavy + environment: + - GITEA_INSTANCE_URL=${GITEA_INSTANCE_URL:-http://localhost:3000} + - GITEA_RUNNER_REGISTRATION_TOKEN=${GITEA_RUNNER_TOKEN} + - GITEA_RUNNER_NAME=labfusion-runner-heavy + - GITEA_RUNNER_LABELS=ubuntu-latest,self-hosted,heavy,java,python + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - runner-data-heavy:/data + - shared-cache:/cache + restart: unless-stopped + deploy: + resources: + limits: + cpus: '4.0' + memory: 8G + reservations: + cpus: '2.0' + memory: 4G + networks: + - gitea-runners + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + + # Runner 2: Light workloads (Node.js/Frontend) + gitea-runner-light: + image: gitea/act_runner:latest + container_name: labfusion-runner-light + environment: + - GITEA_INSTANCE_URL=${GITEA_INSTANCE_URL:-http://localhost:3000} + - GITEA_RUNNER_REGISTRATION_TOKEN=${GITEA_RUNNER_TOKEN} + - GITEA_RUNNER_NAME=labfusion-runner-light + - GITEA_RUNNER_LABELS=ubuntu-latest,self-hosted,light,nodejs,frontend + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - runner-data-light:/data + - shared-cache:/cache + restart: unless-stopped + deploy: + resources: + limits: + cpus: '2.0' + memory: 4G + reservations: + cpus: '1.0' + memory: 2G + networks: + - gitea-runners + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + + # Runner 3: Integration/Docker workloads + gitea-runner-docker: + image: gitea/act_runner:latest + container_name: labfusion-runner-docker + environment: + - GITEA_INSTANCE_URL=${GITEA_INSTANCE_URL:-http://localhost:3000} + - GITEA_RUNNER_REGISTRATION_TOKEN=${GITEA_RUNNER_TOKEN} + - GITEA_RUNNER_NAME=labfusion-runner-docker + - GITEA_RUNNER_LABELS=ubuntu-latest,self-hosted,docker,integration + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - runner-data-docker:/data + - shared-cache:/cache + restart: unless-stopped + deploy: + resources: + limits: + cpus: '6.0' + memory: 12G + reservations: + cpus: '3.0' + memory: 6G + networks: + - gitea-runners + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + + # Optional: Runner for specific tasks (e.g., security scans) + gitea-runner-security: + image: gitea/act_runner:latest + container_name: labfusion-runner-security + environment: + - GITEA_INSTANCE_URL=${GITEA_INSTANCE_URL:-http://localhost:3000} + - GITEA_RUNNER_REGISTRATION_TOKEN=${GITEA_RUNNER_TOKEN} + - GITEA_RUNNER_NAME=labfusion-runner-security + - GITEA_RUNNER_LABELS=ubuntu-latest,self-hosted,security,scan + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - runner-data-security:/data + - shared-cache:/cache + restart: unless-stopped + deploy: + resources: + limits: + cpus: '2.0' + memory: 4G + reservations: + cpus: '1.0' + memory: 2G + networks: + - gitea-runners + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + +volumes: + runner-data-heavy: + driver: local + runner-data-light: + driver: local + runner-data-docker: + driver: local + runner-data-security: + driver: local + shared-cache: + driver: local + +networks: + gitea-runners: + driver: bridge diff --git a/docs/RUNNERS.md b/docs/RUNNERS.md new file mode 100644 index 0000000..93f8264 --- /dev/null +++ b/docs/RUNNERS.md @@ -0,0 +1,312 @@ +# LabFusion Gitea Runners Setup + +This document explains how to set up and manage multiple Gitea Actions runners for the LabFusion project using Docker Compose. + +## Overview + +The LabFusion project uses multiple specialized runners to handle different types of CI/CD workloads: + +- **Heavy Runner**: Java Spring Boot (API Gateway) and Python FastAPI (Service Adapters) +- **Light Runner**: Node.js (API Docs) and React (Frontend) +- **Docker Runner**: Integration tests and Docker builds +- **Security Runner**: Security scans and vulnerability assessments + +## Quick Start + +### 1. Prerequisites + +- Docker and Docker Compose installed +- Gitea instance running +- Runner registration token from Gitea + +### 2. Configuration + +**Windows PowerShell:** +```powershell +# Copy the environment template +Copy-Item env.runners.example .env.runners + +# Edit the configuration +notepad .env.runners +``` + +**Linux/macOS:** +```bash +# Copy the environment template +cp env.runners.example .env.runners + +# Edit the configuration +nano .env.runners +``` + +**Manual Creation (if copy fails):** +Create `.env.runners` file with the following content: + +```bash +# Gitea instance URL (adjust port if different) +GITEA_INSTANCE_URL=http://localhost:3000 + +# Runner registration token (get from Gitea Admin > Actions > Runners) +GITEA_RUNNER_TOKEN=your_runner_registration_token_here +``` + +**Important:** Replace `your_runner_registration_token_here` with your actual token from Gitea Admin > Actions > Runners. + +### 3. Start Runners + +**Linux/macOS:** +```bash +# Make script executable +chmod +x scripts/manage-runners.sh + +# Start all runners +./scripts/manage-runners.sh start +``` + +**Windows PowerShell:** +```powershell +# Start all runners +.\scripts\manage-runners.ps1 start +``` + +**Docker Compose directly:** +```bash +docker-compose -f docker-compose.runners.yml --env-file .env.runners up -d +``` + +## Runner Configuration + +### Resource Allocation + +| Runner | CPU | Memory | Use Case | +|--------|-----|--------|----------| +| Heavy | 4 cores | 8GB | Java/Python builds | +| Light | 2 cores | 4GB | Node.js/Frontend | +| Docker | 6 cores | 12GB | Integration tests | +| Security | 2 cores | 4GB | Security scans | + +### Labels + +Each runner is configured with specific labels for workload routing: + +- **Heavy Runner**: `ubuntu-latest,self-hosted,heavy,java,python` +- **Light Runner**: `ubuntu-latest,self-hosted,light,nodejs,frontend` +- **Docker Runner**: `ubuntu-latest,self-hosted,docker,integration` +- **Security Runner**: `ubuntu-latest,self-hosted,security,scan` + +## Management Commands + +### Using the Management Scripts + +**Linux/macOS:** +```bash +# Start runners +./scripts/manage-runners.sh start + +# Check status +./scripts/manage-runners.sh status + +# View logs +./scripts/manage-runners.sh logs +./scripts/manage-runners.sh logs labfusion-runner-heavy + +# Restart runners +./scripts/manage-runners.sh restart + +# Stop runners +./scripts/manage-runners.sh stop + +# Clean up (removes all data) +./scripts/manage-runners.sh clean +``` + +**Windows PowerShell:** +```powershell +# Start runners +.\scripts\manage-runners.ps1 start + +# Check status +.\scripts\manage-runners.ps1 status + +# View logs +.\scripts\manage-runners.ps1 logs +.\scripts\manage-runners.ps1 logs labfusion-runner-heavy + +# Restart runners +.\scripts\manage-runners.ps1 restart + +# Stop runners +.\scripts\manage-runners.ps1 stop + +# Clean up (removes all data) +.\scripts\manage-runners.ps1 clean +``` + +### Direct Docker Compose Commands + +```bash +# Start all runners +docker-compose -f docker-compose.runners.yml up -d + +# Check status +docker-compose -f docker-compose.runners.yml ps + +# View logs +docker-compose -f docker-compose.runners.yml logs -f + +# Stop runners +docker-compose -f docker-compose.runners.yml down + +# Remove everything (including volumes) +docker-compose -f docker-compose.runners.yml down -v +``` + +## Workflow Configuration + +To use specific runners in your workflows, update the `runs-on` field: + +```yaml +# .gitea/workflows/api-gateway.yml +jobs: + test: + runs-on: [self-hosted, heavy] # Uses heavy runner + +# .gitea/workflows/frontend.yml +jobs: + test: + runs-on: [self-hosted, light] # Uses light runner + +# .gitea/workflows/integration-tests.yml +jobs: + integration: + runs-on: [self-hosted, docker] # Uses docker runner +``` + +## Monitoring + +### Health Checks + +Each runner includes health checks that monitor: +- Container status +- HTTP health endpoint +- Resource usage + +### Logs + +View logs for troubleshooting: + +```bash +# All runners +docker-compose -f docker-compose.runners.yml logs -f + +# Specific runner +docker-compose -f docker-compose.runners.yml logs -f labfusion-runner-heavy +``` + +### Resource Monitoring + +```bash +# Container resource usage +docker stats + +# Volume usage +docker system df -v +``` + +## Troubleshooting + +### Common Issues + +1. **Runners not registering / Token appears empty** + - **Check if `.env.runners` file exists** in the project root + - **Verify the file contains your actual token** (not the placeholder) + - **Make sure you're using the management scripts** (they include `--env-file` parameter) + - **If running Docker Compose directly**, add `--env-file .env.runners`: + ```bash + docker-compose -f docker-compose.runners.yml --env-file .env.runners up -d + ``` + +2. **Runners not registering** + - Check Gitea instance URL and port + - Verify runner token is correct + - Ensure Gitea Actions is enabled + +3. **High resource usage** + - Adjust CPU/memory limits in docker-compose.runners.yml + - Check for stuck jobs in Gitea Actions + +4. **Docker socket issues** + - Ensure Docker socket is accessible: `/var/run/docker.sock` + - Check Docker daemon is running + +5. **Network connectivity** + - Verify runners can reach Gitea instance + - Check firewall settings + +### Debug Mode + +Enable debug logging by adding to `.env.runners`: + +```bash +# Enable debug logging +ACTIONS_RUNNER_DEBUG=1 +``` + +### Reset Runners + +If runners become unresponsive: + +```bash +# Stop and remove all runners +docker-compose -f docker-compose.runners.yml down -v + +# Clean up volumes +docker volume prune -f + +# Restart +docker-compose -f docker-compose.runners.yml up -d +``` + +## Security Considerations + +- Runners run with Docker socket access for container builds +- Each runner has isolated data volumes +- Shared cache volume for build optimization +- Resource limits prevent resource exhaustion +- Health checks ensure runner availability + +## Scaling + +To add more runners: + +1. Copy a runner service in `docker-compose.runners.yml` +2. Update the runner name and labels +3. Adjust resource allocation +4. Restart the compose stack + +Example additional runner: + +```yaml +gitea-runner-additional: + image: gitea/act_runner:latest + container_name: labfusion-runner-additional + environment: + - GITEA_INSTANCE_URL=${GITEA_INSTANCE_URL} + - GITEA_RUNNER_REGISTRATION_TOKEN=${GITEA_RUNNER_TOKEN} + - GITEA_RUNNER_NAME=labfusion-runner-additional + - GITEA_RUNNER_LABELS=ubuntu-latest,self-hosted,additional + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - runner-data-additional:/data + - shared-cache:/cache + restart: unless-stopped +``` + +## Support + +For issues with the runners setup: + +1. Check the troubleshooting section above +2. Review runner logs +3. Verify Gitea Actions configuration +4. Check Docker and Docker Compose installation diff --git a/docs/progress.md b/docs/progress.md index 79f51e0..874de14 100644 --- a/docs/progress.md +++ b/docs/progress.md @@ -217,6 +217,8 @@ The modular structure allows for easy addition of new services: - [x] Update flake8 line length limit to 150 characters for better readability - [x] Create JavaScript/Node.js tests for API docs service and frontend - [x] Fix Gitea Actions compatibility issues with artifact uploads +- [x] Create Docker Compose setup for multiple Gitea runners +- [x] Update all CI/CD pipelines with appropriate runner labels ## Resources - [Project Specifications](specs.md) diff --git a/docs/structure.txt b/docs/structure.txt index 8ab335a..7df8c18 100644 --- a/docs/structure.txt +++ b/docs/structure.txt @@ -97,8 +97,16 @@ labfusion/ │ ├── Dockerfile.dev # Development container │ ├── CLEAN_CODE.md # Clean code documentation │ └── RESILIENCE.md # Frontend resilience features +# Docker Compose for Runners +docker-compose.runners.yml # Multi-runner Docker Compose setup +env.runners.example # Environment template for runners +scripts/ + manage-runners.sh # Linux/macOS runner management script + manage-runners.ps1 # Windows PowerShell runner management script + └── docs/ # Documentation ├── specs.md # Project specifications ├── structure.txt # Project structure ├── progress.md # Development progress tracking - └── CI_CD.md # CI/CD pipeline documentation \ No newline at end of file + ├── CI_CD.md # CI/CD pipeline documentation + └── RUNNERS.md # Gitea runners setup and management \ No newline at end of file diff --git a/env.runners.example b/env.runners.example new file mode 100644 index 0000000..401601f --- /dev/null +++ b/env.runners.example @@ -0,0 +1,14 @@ +# Gitea Runners Environment Configuration +# Copy this file to .env.runners and update with your actual values + +# Gitea instance URL (adjust port if different) +GITEA_INSTANCE_URL=http://localhost:3000 + +# Runner registration token (get this from Gitea Admin > Actions > Runners) +GITEA_RUNNER_TOKEN=your_runner_registration_token_here + +# Optional: Override runner names +# GITEA_RUNNER_NAME_HEAVY=labfusion-runner-heavy +# GITEA_RUNNER_NAME_LIGHT=labfusion-runner-light +# GITEA_RUNNER_NAME_DOCKER=labfusion-runner-docker +# GITEA_RUNNER_NAME_SECURITY=labfusion-runner-security diff --git a/scripts/manage-runners.ps1 b/scripts/manage-runners.ps1 new file mode 100644 index 0000000..a996f42 --- /dev/null +++ b/scripts/manage-runners.ps1 @@ -0,0 +1,208 @@ +# LabFusion Gitea Runners Management Script (PowerShell) +# Usage: .\scripts\manage-runners.ps1 [start|stop|restart|status|logs|clean] + +param( + [Parameter(Position=0)] + [ValidateSet("start", "stop", "restart", "status", "logs", "clean", "help")] + [string]$Command = "help", + + [Parameter(Position=1)] + [string]$RunnerName = "" +) + +$ErrorActionPreference = "Stop" + +$ComposeFile = "docker-compose.runners.yml" +$EnvFile = ".env.runners" + +# Helper functions +function Write-Info { + param([string]$Message) + Write-Host "[INFO] $Message" -ForegroundColor Blue +} + +function Write-Success { + param([string]$Message) + Write-Host "[SUCCESS] $Message" -ForegroundColor Green +} + +function Write-Warning { + param([string]$Message) + Write-Host "[WARNING] $Message" -ForegroundColor Yellow +} + +function Write-Error { + param([string]$Message) + Write-Host "[ERROR] $Message" -ForegroundColor Red +} + +# Check if .env.runners exists +function Test-EnvFile { + if (-not (Test-Path $EnvFile)) { + Write-Error "Environment file $EnvFile not found!" + Write-Info "Please copy env.runners.example to $EnvFile and configure it:" + Write-Info " Copy-Item env.runners.example $EnvFile" + Write-Info " # Edit $EnvFile with your Gitea instance URL and runner token" + exit 1 + } +} + +# Start runners +function Start-Runners { + Write-Info "Starting LabFusion Gitea runners..." + Test-EnvFile + + docker-compose -f $ComposeFile --env-file $EnvFile up -d + + Write-Success "Runners started successfully!" + Write-Info "Runners:" + Write-Info " - Heavy (Java/Python): labfusion-runner-heavy" + Write-Info " - Light (Node.js/Frontend): labfusion-runner-light" + Write-Info " - Docker (Integration): labfusion-runner-docker" + Write-Info " - Security (Scans): labfusion-runner-security" + + # Wait a moment for health checks + Start-Sleep -Seconds 5 + Show-Status +} + +# Stop runners +function Stop-Runners { + Write-Info "Stopping LabFusion Gitea runners..." + + docker-compose -f $ComposeFile down + + Write-Success "Runners stopped successfully!" +} + +# Restart runners +function Restart-Runners { + Write-Info "Restarting LabFusion Gitea runners..." + Stop-Runners + Start-Sleep -Seconds 2 + Start-Runners +} + +# Show runner status +function Show-Status { + Write-Info "LabFusion Gitea Runners Status:" + Write-Host "" + + # Check if compose file exists + if (-not (Test-Path $ComposeFile)) { + Write-Error "Docker Compose file $ComposeFile not found!" + exit 1 + } + + # Show container status + docker-compose -f $ComposeFile ps + + Write-Host "" + Write-Info "Runner Health Status:" + + # Check each runner's health + $runners = @("labfusion-runner-heavy", "labfusion-runner-light", "labfusion-runner-docker", "labfusion-runner-security") + + foreach ($runner in $runners) { + $container = docker ps --format "table {{.Names}}\t{{.Status}}" | Select-String $runner + if ($container) { + try { + $health = docker inspect --format='{{.State.Health.Status}}' $runner 2>$null + if ($health) { + switch ($health) { + "healthy" { Write-Success "$runner`: $health" } + "unhealthy" { Write-Error "$runner`: $health" } + "starting" { Write-Warning "$runner`: $health" } + default { Write-Warning "$runner`: $health" } + } + } else { + Write-Warning "$runner`: health check not available" + } + } catch { + Write-Warning "$runner`: health check failed" + } + } else { + Write-Error "$runner`: not running" + } + } +} + +# Show logs +function Show-Logs { + param([string]$Runner = "") + + if ($Runner) { + Write-Info "Showing logs for $Runner..." + docker-compose -f $ComposeFile logs -f $Runner + } else { + Write-Info "Showing logs for all runners..." + docker-compose -f $ComposeFile logs -f + } +} + +# Clean up runners and data +function Clean-Runners { + $response = Read-Host "This will remove all runners and their data. Are you sure? (y/N)" + + if ($response -match "^[Yy]$") { + Write-Info "Cleaning up runners and data..." + + # Stop and remove containers + docker-compose -f $ComposeFile down -v + + # Remove volumes + try { + $volumes = docker volume ls -q | Where-Object { $_ -match "runner-data" } + if ($volumes) { + docker volume rm $volumes + } + docker volume rm shared-cache 2>$null + } catch { + Write-Warning "Some volumes could not be removed (this is normal if they don't exist)" + } + + Write-Success "Cleanup completed!" + } else { + Write-Info "Cleanup cancelled." + } +} + +# Show help +function Show-Help { + Write-Host "LabFusion Gitea Runners Management Script (PowerShell)" + Write-Host "" + Write-Host "Usage: .\scripts\manage-runners.ps1 [COMMAND] [RUNNER_NAME]" + Write-Host "" + Write-Host "Commands:" + Write-Host " start Start all runners" + Write-Host " stop Stop all runners" + Write-Host " restart Restart all runners" + Write-Host " status Show runner status and health" + Write-Host " logs Show logs for all runners" + Write-Host " logs [runner] Show logs for specific runner" + Write-Host " clean Remove all runners and data (destructive)" + Write-Host " help Show this help message" + Write-Host "" + Write-Host "Examples:" + Write-Host " .\scripts\manage-runners.ps1 start" + Write-Host " .\scripts\manage-runners.ps1 status" + Write-Host " .\scripts\manage-runners.ps1 logs labfusion-runner-heavy" + Write-Host " .\scripts\manage-runners.ps1 clean" +} + +# Main script logic +switch ($Command) { + "start" { Start-Runners } + "stop" { Stop-Runners } + "restart" { Restart-Runners } + "status" { Show-Status } + "logs" { Show-Logs -Runner $RunnerName } + "clean" { Clean-Runners } + "help" { Show-Help } + default { + Write-Error "Unknown command: $Command" + Write-Host "" + Show-Help + exit 1 + } +} diff --git a/scripts/manage-runners.sh b/scripts/manage-runners.sh new file mode 100644 index 0000000..464e9da --- /dev/null +++ b/scripts/manage-runners.sh @@ -0,0 +1,209 @@ +#!/bin/bash + +# LabFusion Gitea Runners Management Script +# Usage: ./scripts/manage-runners.sh [start|stop|restart|status|logs|clean] + +set -e + +COMPOSE_FILE="docker-compose.runners.yml" +ENV_FILE=".env.runners" + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Helper functions +log_info() { + echo -e "${BLUE}[INFO]${NC} $1" +} + +log_success() { + echo -e "${GREEN}[SUCCESS]${NC} $1" +} + +log_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# Check if .env.runners exists +check_env_file() { + if [ ! -f "$ENV_FILE" ]; then + log_error "Environment file $ENV_FILE not found!" + log_info "Please copy env.runners.example to $ENV_FILE and configure it:" + log_info " cp env.runners.example $ENV_FILE" + log_info " # Edit $ENV_FILE with your Gitea instance URL and runner token" + exit 1 + fi +} + +# Start runners +start_runners() { + log_info "Starting LabFusion Gitea runners..." + check_env_file + + docker-compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" up -d + + log_success "Runners started successfully!" + log_info "Runners:" + log_info " - Heavy (Java/Python): labfusion-runner-heavy" + log_info " - Light (Node.js/Frontend): labfusion-runner-light" + log_info " - Docker (Integration): labfusion-runner-docker" + log_info " - Security (Scans): labfusion-runner-security" + + # Wait a moment for health checks + sleep 5 + show_status +} + +# Stop runners +stop_runners() { + log_info "Stopping LabFusion Gitea runners..." + + docker-compose -f "$COMPOSE_FILE" down + + log_success "Runners stopped successfully!" +} + +# Restart runners +restart_runners() { + log_info "Restarting LabFusion Gitea runners..." + stop_runners + sleep 2 + start_runners +} + +# Show runner status +show_status() { + log_info "LabFusion Gitea Runners Status:" + echo + + # Check if compose file exists + if [ ! -f "$COMPOSE_FILE" ]; then + log_error "Docker Compose file $COMPOSE_FILE not found!" + exit 1 + fi + + # Show container status + docker-compose -f "$COMPOSE_FILE" ps + + echo + log_info "Runner Health Status:" + + # Check each runner's health + for runner in labfusion-runner-heavy labfusion-runner-light labfusion-runner-docker labfusion-runner-security; do + if docker ps --format "table {{.Names}}\t{{.Status}}" | grep -q "$runner"; then + status=$(docker inspect --format='{{.State.Health.Status}}' "$runner" 2>/dev/null || echo "unknown") + case $status in + "healthy") + log_success "$runner: $status" + ;; + "unhealthy") + log_error "$runner: $status" + ;; + "starting") + log_warning "$runner: $status" + ;; + *) + log_warning "$runner: $status" + ;; + esac + else + log_error "$runner: not running" + fi + done +} + +# Show logs +show_logs() { + local runner=${2:-""} + + if [ -n "$runner" ]; then + log_info "Showing logs for $runner..." + docker-compose -f "$COMPOSE_FILE" logs -f "$runner" + else + log_info "Showing logs for all runners..." + docker-compose -f "$COMPOSE_FILE" logs -f + fi +} + +# Clean up runners and data +clean_runners() { + log_warning "This will remove all runners and their data. Are you sure? (y/N)" + read -r response + + if [[ "$response" =~ ^[Yy]$ ]]; then + log_info "Cleaning up runners and data..." + + # Stop and remove containers + docker-compose -f "$COMPOSE_FILE" down -v + + # Remove volumes + docker volume rm $(docker volume ls -q | grep runner-data) 2>/dev/null || true + docker volume rm shared-cache 2>/dev/null || true + + log_success "Cleanup completed!" + else + log_info "Cleanup cancelled." + fi +} + +# Show help +show_help() { + echo "LabFusion Gitea Runners Management Script" + echo + echo "Usage: $0 [COMMAND]" + echo + echo "Commands:" + echo " start Start all runners" + echo " stop Stop all runners" + echo " restart Restart all runners" + echo " status Show runner status and health" + echo " logs Show logs for all runners" + echo " logs [runner] Show logs for specific runner" + echo " clean Remove all runners and data (destructive)" + echo " help Show this help message" + echo + echo "Examples:" + echo " $0 start" + echo " $0 status" + echo " $0 logs labfusion-runner-heavy" + echo " $0 clean" +} + +# Main script logic +case "${1:-help}" in + start) + start_runners + ;; + stop) + stop_runners + ;; + restart) + restart_runners + ;; + status) + show_status + ;; + logs) + show_logs "$@" + ;; + clean) + clean_runners + ;; + help|--help|-h) + show_help + ;; + *) + log_error "Unknown command: $1" + echo + show_help + exit 1 + ;; +esac