#!/bin/bash # Unified cleanup script for release preparation # Usage: ./scripts/release/cleanup.sh [all|docker|podman|logs|secrets|state|testdata|list] set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" cd "$REPO_ROOT" # 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 -e "${BLUE}=== $1 ===${NC}" } print_success() { echo -e "${GREEN}✓${NC} $1" } print_warn() { echo -e "${YELLOW}⚠${NC} $1" } print_error() { echo -e "${RED}✗${NC} $1" } # Docker cleanup cleanup_docker() { print_header "Docker Compose Cleanup" # Stop all project-related containers docker-compose -f deployments/docker-compose.dev.yml down --volumes --remove-orphans 2>/dev/null || true docker-compose -f deployments/docker-compose.local.yml down --volumes --remove-orphans 2>/dev/null || true docker-compose -f tests/e2e/docker-compose.logs-debug.yml down --volumes --remove-orphans 2>/dev/null || true # Remove project-specific images (keep base images) docker images --filter "reference=fetchml*" --format "{{.ID}}" | xargs -r docker rmi -f 2>/dev/null || true docker images --filter "reference=*/fetchml*" --format "{{.ID}}" | xargs -r docker rmi -f 2>/dev/null || true # Remove dangling volumes docker volume ls -q --filter dangling=true | xargs -r docker volume rm 2>/dev/null || true # Prune build cache (keep for 24h) docker builder prune --keep-duration 24h --force 2>/dev/null || true print_success "Docker cleanup complete" } # Podman cleanup cleanup_podman() { print_header "Podman Cleanup" # Stop all fetchml containers podman ps -a --filter "name=fetchml" --format "{{.Names}}" 2>/dev/null | xargs -r podman stop 2>/dev/null || true podman ps -a --filter "name=ml-*" --format "{{.Names}}" 2>/dev/null | xargs -r podman stop 2>/dev/null || true # Remove stopped containers podman ps -a --filter "name=fetchml" --format "{{.ID}}" 2>/dev/null | xargs -r podman rm 2>/dev/null || true podman ps -a --filter "name=ml-*" --format "{{.ID}}" 2>/dev/null | xargs -r podman rm 2>/dev/null || true podman ps -a --filter "name=jupyter-*" --format "{{.ID}}" 2>/dev/null | xargs -r podman rm 2>/dev/null || true # Remove project images podman images --filter "reference=fetchml*" --format "{{.ID}}" 2>/dev/null | xargs -r podman rmi -f 2>/dev/null || true # Remove unused volumes podman volume ls -q 2>/dev/null | grep -E "(fetchml|jupyter|ml-)" | xargs -r podman volume rm 2>/dev/null || true # Clean up pods podman pod ls --filter "name=ml-" --format "{{.Name}}" 2>/dev/null | xargs -r podman pod rm -f 2>/dev/null || true print_success "Podman cleanup complete" } # Log cleanup cleanup_logs() { print_header "Log Cleanup" # Remove old logs (keep last 30 days) find . -name "*.log" -mtime +30 -delete 2>/dev/null || true find . -name "audit*.log" -mtime +30 -delete 2>/dev/null || true # Truncate current logs (keep file, clear content) find . -name "fetchml*.log" -size +100M -exec sh -c '> {}' \; 2>/dev/null || true # Remove crash dumps rm -f core.* 2>/dev/null || true rm -f *.prof 2>/dev/null || true rm -f /tmp/fetchml_*.prof 2>/dev/null || true print_success "Log cleanup complete" } # Secret cleanup cleanup_secrets() { print_header "Secret Cleanup" # Remove any Podman secrets created during testing podman secret ls --format "{{.Name}}" 2>/dev/null | grep -E "(fetchml|test|dev)" | xargs -r podman secret rm 2>/dev/null || true # Clear temporary credential files rm -f /tmp/fetchml_*_key 2>/dev/null || true rm -f /tmp/test_*_secret 2>/dev/null || true rm -f /tmp/*.pem 2>/dev/null || true # Reset example config permissions (ensure they're not world-readable) find configs/ -name "*.yaml" -o -name "*.yml" -o -name "*.toml" 2>/dev/null | while read f; do if [[ "$f" != *example* ]]; then chmod 600 "$f" 2>/dev/null || true fi done print_success "Secret cleanup complete" } # State cleanup cleanup_state() { print_header "State File Cleanup" # Remove local state files rm -f data/active/jupyter/fetch_ml_jupyter_*.json 2>/dev/null || true rm -f data/active/jupyter/fetch_ml_jupyter_workspaces.json 2>/dev/null || true rm -rf data/active/jupyter/trash/* 2>/dev/null || true # Clean queue state rm -f data/queue/*.tmp 2>/dev/null || true rm -f data/queue/.*.lock 2>/dev/null || true # Remove pid files rm -f /tmp/fetchml*.pid 2>/dev/null || true print_success "State cleanup complete" } # Test data cleanup cleanup_testdata() { print_header "Test Data Cleanup" # Remove test experiment data rm -rf data/experiments/test_* 2>/dev/null || true rm -rf data/active/workspaces/test_* 2>/dev/null || true # Clean up benchmark artifacts if [ -f ./scripts/maintenance/cleanup-benchmarks.sh ]; then ./scripts/maintenance/cleanup-benchmarks.sh all 2>/dev/null || true fi # Remove temporary test databases rm -f /tmp/fetchml_test_*.sqlite 2>/dev/null || true rm -f /tmp/fetchml_test_*.db 2>/dev/null || true # Clean Jupyter service test data rm -rf /tmp/jupyter-test-* 2>/dev/null || true rm -f /tmp/fetch_ml_jupyter_*.json 2>/dev/null || true print_success "Test data cleanup complete" } # List available cleanup targets list_targets() { echo "Available cleanup targets:" echo " all - Run all cleanup operations" echo " docker - Clean Docker containers, images, and volumes" echo " podman - Clean Podman containers, images, and pods" echo " logs - Remove old logs and crash dumps" echo " secrets - Remove temporary credentials and reset permissions" echo " state - Clean runtime state files and PID files" echo " testdata - Remove test data and temporary databases" } # Show usage usage() { echo "Usage: $0 [TARGET]" echo "" list_targets echo "" echo "Examples:" echo " $0 all # Clean everything (default)" echo " $0 docker # Clean only Docker resources" echo " $0 list # Show available targets" } # Main main() { local target="${1:-all}" case "$target" in all) cleanup_docker cleanup_podman cleanup_logs cleanup_secrets cleanup_state cleanup_testdata echo "" print_header "All cleanup operations complete" ;; docker) cleanup_docker ;; podman) cleanup_podman ;; logs) cleanup_logs ;; secrets) cleanup_secrets ;; state) cleanup_state ;; testdata) cleanup_testdata ;; list|--list|-l) list_targets ;; help|--help|-h) usage exit 0 ;; *) print_error "Unknown target: $target" usage exit 1 ;; esac } main "$@"