diff --git a/scripts/cleanup.sh b/scripts/cleanup.sh deleted file mode 100755 index 612762a..0000000 --- a/scripts/cleanup.sh +++ /dev/null @@ -1,693 +0,0 @@ -#!/bin/bash - -# Sharenet Cleanup Script -# This script cleans up Docker resources and registry images - -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 -CLEANUP_TYPE="${CLEANUP_TYPE:-ci-cd}" # ci-cd or production -REGISTRY_DIR="${REGISTRY_DIR:-/opt/registry}" -DRY_RUN="${DRY_RUN:-false}" - -# Critical infrastructure protection -CRITICAL_CONTAINERS="harbor-core,harbor-db,harbor-jobservice,harbor-log,harbor-portal,nginx,redis,registry,registryctl,trivy-adapter" -CRITICAL_IMAGES="goharbor,forgejo-runner" -CRITICAL_VOLUMES="harbor" -CRITICAL_NETWORKS="harbor" - -# 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" -} - -get_unused_images() { - # Get unused images (excluding Harbor images) with detailed information - # This includes both dangling images and tagged images not used by running containers - - # Get all images (excluding Harbor images) - local all_images=$(docker image ls --format "{{.Repository}}:{{.Tag}} ({{.ID}}) - Size: {{.Size}}, Created: {{.CreatedAt}}" | grep -v "goharbor" | grep -v "harbor" || true) - - if [ -n "$all_images" ]; then - echo "$all_images" | while read -r image; do - if [ -n "$image" ]; then - # Extract image ID from the format - local image_id=$(echo "$image" | sed 's/.*(\([a-f0-9]*\)).*/\1/') - - if [ -n "$image_id" ]; then - # Check if this image is used by any running containers - local used_by_containers=$(docker ps --format "{{.Image}}" | grep -q "$image_id" && echo "used" || echo "unused") - - # Check if this image is used by any stopped containers - local used_by_stopped=$(docker ps -a --format "{{.Image}}" | grep -q "$image_id" && echo "used" || echo "unused") - - # If image is not used by any containers, it's safe to remove - if [ "$used_by_containers" = "unused" ] && [ "$used_by_stopped" = "unused" ]; then - echo "$image (unused - safe to remove)" - fi - fi - fi - done - fi -} - -get_unused_volumes() { - # Get unused volumes (excluding Harbor volumes) - just IDs for cleanup - docker volume ls -q --filter "dangling=true" | grep -v "harbor" | grep -v "registry" || true -} - -get_unused_volumes_with_usage() { - # Get unused volumes (excluding Harbor volumes) with container usage info - local volumes=$(docker volume ls -q --filter "dangling=true" | grep -v "harbor" | grep -v "registry" || true) - - if [ -n "$volumes" ]; then - echo "$volumes" | while read -r volume; do - if [ -n "$volume" ]; then - # Get containers using this volume - local containers=$(docker ps -a --filter "volume=$volume" --format "{{.Names}}" 2>/dev/null || echo "") - # Get volume creation time - local created=$(docker volume inspect "$volume" --format "{{.CreatedAt}}" 2>/dev/null || echo "unknown") - # Get volume driver - local driver=$(docker volume inspect "$volume" --format "{{.Driver}}" 2>/dev/null || echo "local") - - # Format the output with volume ID and usage info - if [ -n "$containers" ]; then - echo "$volume (used by: $containers, created: $created, driver: $driver)" - else - echo "$volume (unused - safe to remove, created: $created, driver: $driver)" - fi - fi - done - fi -} - -get_unused_volumes_detailed() { - # Get unused volumes (excluding Harbor volumes) with detailed information for display - local volumes=$(docker volume ls -q --filter "dangling=true" | grep -v "harbor" | grep -v "registry" || true) - - if [ -n "$volumes" ]; then - echo "$volumes" | while read -r volume; do - if [ -n "$volume" ]; then - # Get containers using this volume - local containers=$(docker ps -a --filter "volume=$volume" --format "{{.Names}}" 2>/dev/null || echo "") - # Get volume creation time - local created=$(docker volume inspect "$volume" --format "{{.CreatedAt}}" 2>/dev/null || echo "unknown") - # Get volume driver - local driver=$(docker volume inspect "$volume" --format "{{.Driver}}" 2>/dev/null || echo "local") - - # Format the output with volume ID and usage info - if [ -n "$containers" ]; then - echo "$volume (used by: $containers, created: $created, driver: $driver)" - else - echo "$volume (unused - safe to remove, created: $created, driver: $driver)" - fi - fi - done - fi -} - -get_unused_networks() { - # Get unused networks (excluding Harbor networks) with detailed information - docker network ls --filter "type=custom" --format "{{.Name}} ({{.Driver}}) - Created: {{.CreatedAt}}" | grep -v "harbor" | grep -v "registry" || true -} - -get_protected_containers() { - # Get all critical containers that are running - local protected_containers="" - IFS=',' read -ra CONTAINERS <<< "$CRITICAL_CONTAINERS" - for container in "${CONTAINERS[@]}"; do - if docker ps --format "{{.Names}}" | grep -q "^${container}$"; then - if [ -n "$protected_containers" ]; then - protected_containers="$protected_containers - - $container (Harbor container)" - else - protected_containers=" - $container (Harbor container)" - fi - fi - done - echo "$protected_containers" -} - -get_protected_volumes() { - # Get Harbor volumes that would be protected - docker volume ls -q --filter "dangling=true" | grep -E "(harbor|registry)" || true -} - -get_protected_images() { - # Get Harbor images that would be protected - docker images --format "{{.Repository}}:{{.Tag}}" | grep -E "(goharbor|harbor)" || true -} - -get_protected_networks() { - # Get Harbor networks that would be protected - docker network ls --format "{{.Name}}" | grep -E "(harbor|registry)" || true -} - -check_critical_infrastructure() { - log_info "Checking critical infrastructure status..." - - local missing_containers="" - IFS=',' read -ra CONTAINERS <<< "$CRITICAL_CONTAINERS" - - for container in "${CONTAINERS[@]}"; do - if ! docker ps --format "{{.Names}}" | grep -q "^${container}$"; then - if [ -n "$missing_containers" ]; then - missing_containers="$missing_containers, $container" - else - missing_containers="$container" - fi - fi - done - - if [ -n "$missing_containers" ]; then - log_warning "Some critical containers are not running: $missing_containers" - log_warning "This may indicate infrastructure issues. Proceed with caution." - else - log_success "All critical infrastructure containers are running" - fi - - # Check Forgejo runner service - if systemctl is-active --quiet forgejo-runner.service; then - log_success "Forgejo runner service is running" - else - log_warning "Forgejo runner service is not running" - fi - - echo -} - -label_critical_containers() { - log_info "Labeling critical containers for protection..." - - IFS=',' read -ra CONTAINERS <<< "$CRITICAL_CONTAINERS" - - for container in "${CONTAINERS[@]}"; do - if docker ps --format "{{.Names}}" | grep -q "^${container}$"; then - # Add protection labels - docker update --label critical=infrastructure "$container" 2>/dev/null || true - docker update --label protected=true "$container" 2>/dev/null || true - - # Add specific labels based on container type - if [[ "$container" == harbor* ]]; then - docker update --label service=harbor "$container" 2>/dev/null || true - elif [[ "$container" == forgejo* ]]; then - docker update --label service=forgejo "$container" 2>/dev/null || true - fi - fi - done - - log_success "Critical containers labeled for protection" - echo -} - -protect_harbor_volumes() { - log_info "Identifying and protecting Harbor volumes..." - - # Use the same logic as the dry-run section to find Harbor volumes - HARBOR_VOLUMES=$(docker volume ls -q --filter "dangling=true" | grep -E "(harbor|registry)" || true) - - if [ -n "$HARBOR_VOLUMES" ]; then - log_info "Found Harbor volumes:" - echo "$HARBOR_VOLUMES" | while read -r vol; do - if [ -n "$vol" ]; then - echo " - $vol (PROTECTED)" - fi - done - else - log_info "No Harbor volumes found" - fi - - log_success "Harbor volumes identified for protection" - echo -} - -show_help() { - cat << EOF -Sharenet Cleanup Script - -Usage: $0 [OPTIONS] - -Options: - --type TYPE Cleanup type: ci-cd or production (default: ci-cd) - --registry-dir DIR Registry directory (default: /opt/registry) - --dry-run Show what would be done without executing - --help Show this help message - -Environment Variables: - CLEANUP_TYPE Set cleanup type (ci-cd/production) - REGISTRY_DIR Set registry directory path - DRY_RUN Set to 'true' for dry run mode - -Examples: - $0 # Cleanup CI/CD environment - $0 --type production # Cleanup production environment - $0 --dry-run # Show what would be cleaned - DRY_RUN=true $0 # Dry run mode -EOF -} - -cleanup_docker_resources() { - if [ "$DRY_RUN" = "true" ]; then - echo - echo "==================================================================================" - echo " 🚨 DRY RUN MODE 🚨" - echo " No resources will be deleted" - echo "==================================================================================" - echo - log_info "Checking what would be cleaned up..." - echo - - # Get lists using shared functions - local unused_images=$(get_unused_images) - local unused_volumes=$(get_unused_volumes_with_usage) - local unused_networks=$(get_unused_networks) - local protected_containers=$(get_protected_containers) - local protected_volumes=$(get_protected_volumes) - local protected_images=$(get_protected_images) - local protected_networks=$(get_protected_networks) - - # Section 1: ITEMS PROTECTED - echo "==================================================================================" - echo " 🛡️ ITEMS PROTECTED 🛡️" - echo "==================================================================================" - echo - - if [ -n "$protected_containers" ]; then - log_info "Protected Containers:" - echo "$protected_containers" - echo - else - log_info "Protected Containers: None found" - echo - fi - - if [ -n "$protected_volumes" ]; then - log_info "Protected Volumes:" - echo "$protected_volumes" | while read -r volume; do - echo " - $volume (Harbor volume)" - done - echo - else - log_info "Protected Volumes: None found" - echo - fi - - if [ -n "$protected_images" ]; then - log_info "Protected Images:" - echo "$protected_images" | while read -r image; do - echo " - $image (Harbor image)" - done - echo - else - log_info "Protected Images: None found" - echo - fi - - if [ -n "$protected_networks" ]; then - log_info "Protected Networks:" - echo "$protected_networks" | while read -r network; do - echo " - $network (Harbor network)" - done - echo - else - log_info "Protected Networks: None found" - echo - fi - - # Section 2: ITEMS REMOVED - echo "==================================================================================" - echo " 🗑️ ITEMS REMOVED 🗑️" - echo "==================================================================================" - echo - - # Clean up unused images - if [ -n "$unused_images" ]; then - log_info "Images removed:" - echo "$unused_images" | while read -r image; do - echo " - $image" - done - echo - - log_info "Removing unused images..." - echo "$unused_images" | while read -r image; do - # Extract image ID from the format "repo:tag (id) - Size: size, Created: date" - local image_id=$(echo "$image" | sed 's/.*(\([a-f0-9]*\)).*/\1/') - if [ -n "$image_id" ]; then - # First try to remove by image ID (this will remove all tags) - docker rmi "$image_id" 2>/dev/null || { - # If that fails, try to remove by repository:tag - local repo_tag=$(echo "$image" | cut -d' ' -f1) - if [ -n "$repo_tag" ]; then - docker rmi "$repo_tag" 2>/dev/null || log_warning "Failed to remove image: $repo_tag" - fi - } - fi - done - log_success "Unused images removed" - else - log_info "Images removed: None found" - log_info "No unused images to remove" - fi - - # Clean up unused volumes - if [ -n "$unused_volumes" ]; then - log_info "Volumes removed:" - local volumes_with_usage=$(get_unused_volumes_with_usage) - if [ -n "$volumes_with_usage" ]; then - echo "$volumes_with_usage" | while read -r volume_info; do - if [ -n "$volume_info" ]; then - echo " - $volume_info" - fi - done - fi - echo - - log_info "Removing unused volumes..." - # Now remove the volumes - echo "$unused_volumes" | while read -r volume; do - if [ -n "$volume" ]; then - docker volume rm "$volume" 2>/dev/null || log_warning "Failed to remove volume: $volume" - fi - done - log_success "Unused volumes removed" - else - log_info "Volumes removed: None found" - log_info "No unused volumes to remove" - fi - - # Clean up unused networks - if [ -n "$unused_networks" ]; then - log_info "Networks removed:" - echo "$unused_networks" | while read -r network; do - echo " - $network" - done - echo - - log_info "Removing unused networks..." - echo "$unused_networks" | while read -r network; do - # Extract network name from the format "name (driver) - Created: date" - local network_name=$(echo "$network" | cut -d' ' -f1) - if [ -n "$network_name" ]; then - docker network rm "$network_name" 2>/dev/null || log_warning "Failed to remove network: $network_name" - fi - done - log_success "Unused networks removed" - else - log_info "Networks removed: None found" - log_info "No unused networks to remove" - fi - - echo "==================================================================================" - log_success "Dry run completed. No resources were deleted." - echo "==================================================================================" - return - fi - - # Get lists using shared functions - local unused_images=$(get_unused_images) - local unused_volumes=$(get_unused_volumes) - local unused_networks=$(get_unused_networks) - local protected_containers=$(get_protected_containers) - local protected_volumes=$(get_protected_volumes) - local protected_images=$(get_protected_images) - local protected_networks=$(get_protected_networks) - - # Section 1: ITEMS PROTECTED - echo "==================================================================================" - echo " 🛡️ ITEMS PROTECTED 🛡️" - echo "==================================================================================" - echo - - if [ -n "$protected_containers" ]; then - log_info "Protected Containers:" - echo "$protected_containers" - echo - else - log_info "Protected Containers: None found" - echo - fi - - if [ -n "$protected_volumes" ]; then - log_info "Protected Volumes:" - echo "$protected_volumes" | while read -r volume; do - echo " - $volume (Harbor volume)" - done - echo - else - log_info "Protected Volumes: None found" - echo - fi - - if [ -n "$protected_images" ]; then - log_info "Protected Images:" - echo "$protected_images" | while read -r image; do - echo " - $image (Harbor image)" - done - echo - else - log_info "Protected Images: None found" - echo - fi - - if [ -n "$protected_networks" ]; then - log_info "Protected Networks:" - echo "$protected_networks" | while read -r network; do - echo " - $network (Harbor network)" - done - echo - else - log_info "Protected Networks: None found" - echo - fi - - # Section 2: ITEMS REMOVED - echo "==================================================================================" - echo " 🗑️ ITEMS REMOVED 🗑️" - echo "==================================================================================" - echo - - # Clean up unused images - if [ -n "$unused_images" ]; then - log_info "Images removed:" - echo "$unused_images" | while read -r image; do - echo " - $image" - done - echo - - log_info "Removing unused images..." - echo "$unused_images" | while read -r image; do - # Extract image ID from the format "repo:tag (id) - Size: size, Created: date" - local image_id=$(echo "$image" | sed 's/.*(\([a-f0-9]*\)).*/\1/') - if [ -n "$image_id" ]; then - # First try to remove by image ID (this will remove all tags) - docker rmi "$image_id" 2>/dev/null || { - # If that fails, try to remove by repository:tag - local repo_tag=$(echo "$image" | cut -d' ' -f1) - if [ -n "$repo_tag" ]; then - docker rmi "$repo_tag" 2>/dev/null || log_warning "Failed to remove image: $repo_tag" - fi - } - fi - done - log_success "Unused images removed" - else - log_info "Images removed: None found" - log_info "No unused images to remove" - fi - - # Clean up unused volumes - if [ -n "$unused_volumes" ]; then - log_info "Volumes removed:" - local volumes_with_usage=$(get_unused_volumes_with_usage) - if [ -n "$volumes_with_usage" ]; then - echo "$volumes_with_usage" | while read -r volume_info; do - if [ -n "$volume_info" ]; then - echo " - $volume_info" - fi - done - fi - echo - - log_info "Removing unused volumes..." - # Now remove the volumes - echo "$unused_volumes" | while read -r volume; do - if [ -n "$volume" ]; then - docker volume rm "$volume" 2>/dev/null || log_warning "Failed to remove volume: $volume" - fi - done - log_success "Unused volumes removed" - else - log_info "Volumes removed: None found" - log_info "No unused volumes to remove" - fi - - # Clean up unused networks - if [ -n "$unused_networks" ]; then - log_info "Networks removed:" - echo "$unused_networks" | while read -r network; do - echo " - $network" - done - echo - - log_info "Removing unused networks..." - echo "$unused_networks" | while read -r network; do - # Extract network name from the format "name (driver) - Created: date" - local network_name=$(echo "$network" | cut -d' ' -f1) - if [ -n "$network_name" ]; then - docker network rm "$network_name" 2>/dev/null || log_warning "Failed to remove network: $network_name" - fi - done - log_success "Unused networks removed" - else - log_info "Networks removed: None found" - log_info "No unused networks to remove" - fi - - echo "==================================================================================" - log_success "Docker resources cleanup completed (critical infrastructure protected)" - echo "==================================================================================" -} - -cleanup_registry() { - if [ "$CLEANUP_TYPE" != "ci-cd" ]; then - log_info "Skipping registry cleanup (not CI/CD environment)" - return - fi - - log_info "Cleaning up Harbor registry..." - - # Check if Harbor containers are running - if ! docker ps --format "{{.Names}}" | grep -q harbor; then - log_warning "Harbor containers are not running, skipping registry cleanup" - return - fi - - if [ "$DRY_RUN" = "true" ]; then - log_warning "DRY RUN MODE - No changes will be made" - echo "Would run: Harbor registry garbage collection via API" - return - fi - - # Harbor garbage collection is typically done via the Harbor UI or API - # For now, we'll just log that manual cleanup may be needed - log_info "Harbor registry cleanup: Use Harbor UI to clean up old images" - log_info "Manual cleanup: Go to Harbor UI → Projects → Select project → Artifacts → Delete old tags" - - log_success "Harbor registry cleanup info provided" -} - -cleanup_production() { - log_info "Cleaning up production environment..." - - # Check if we're in the application directory - if [ -f "docker-compose.yml" ]; then - log_info "Found docker-compose.yml, cleaning up application resources..." - - if [ "$DRY_RUN" = "true" ]; then - log_warning "DRY RUN MODE - No changes will be made" - echo "Would run: docker-compose down" - echo "Would run: docker image prune -f" - return - fi - - # Stop containers to free up resources - log_info "Stopping application containers..." - docker-compose down - - # Clean up Docker resources - cleanup_docker_resources - - # Start containers again - log_info "Starting application containers..." - docker-compose up -d - - log_success "Production cleanup completed" - else - log_warning "Not in application directory (docker-compose.yml not found)" - cleanup_docker_resources - fi -} - -cleanup_ci_cd() { - log_info "Cleaning up CI/CD environment..." - - # Check critical infrastructure before cleanup - check_critical_infrastructure - - # Label critical containers for protection - label_critical_containers - - # Protect Harbor volumes - protect_harbor_volumes - - # Clean up Docker resources (this will show the organized sections) - cleanup_docker_resources - - # Clean up registry - cleanup_registry - - log_success "CI/CD cleanup completed" -} - -# Parse command line arguments -while [[ $# -gt 0 ]]; do - case $1 in - --type) - CLEANUP_TYPE="$2" - shift 2 - ;; - --registry-dir) - REGISTRY_DIR="$2" - shift 2 - ;; - --dry-run) - DRY_RUN="true" - shift - ;; - --help|-h) - show_help - exit 0 - ;; - *) - log_error "Unknown option: $1" - show_help - exit 1 - ;; - esac -done - -# Main cleanup logic -case "$CLEANUP_TYPE" in - production) - cleanup_production - ;; - ci-cd) - cleanup_ci_cd - ;; - *) - log_error "Invalid cleanup type: $CLEANUP_TYPE" - log_error "Valid types: production, ci-cd" - exit 1 - ;; -esac - -log_success "Cleanup completed successfully" \ No newline at end of file