#!/bin/bash # Function to display help show_help() { echo "=== Usage: $0 [config_path] ===" echo "" echo "Description:" echo " Runs garbage collector in Docker registry container and restarts it" echo "" echo "Arguments:" echo " - name or ID of Docker registry container (required)" echo " [config_path] - path to configuration file inside container (optional)" echo "" echo "If config path is not specified, script automatically searches in:" echo " - /etc/docker/registry/config.yml" echo " - /etc/distribution/config.yml" echo "" echo "Examples:" echo " $0 registry" echo " $0 my-registry-container" echo " $0 registry /etc/distribution/config.yml" echo " $0 \$(docker ps -qf 'name=registry') /custom/path/config.yml" } # Function to find configuration file find_config() { local container="$1" local config_paths=( "/etc/docker/registry/config.yml" "/etc/distribution/config.yml" ) # Add custom path if specified if [ -n "$2" ]; then config_paths=("$2" "${config_paths[@]}") fi echo "[Search] Looking for configuration file in container..." for path in "${config_paths[@]}"; do if docker exec "$container" test -f "$path" 2>/dev/null; then echo " [OK] Configuration file found: ${path}" CONFIG_PATH="$path" return 0 else echo " [-] Not found: ${path}" fi done return 1 } # Function to find all possible configs find_all_configs() { local container="$1" echo "[Search] Performing extended search for configuration files..." # Look for all .yml and .yaml files that could be registry configs local configs=$(docker exec "$container" find / -type f \( -name "config.yml" -o -name "config.yaml" \) 2>/dev/null | grep -E "(registry|distribution|docker)" | head -10) if [ -n "$configs" ]; then echo " [OK] Possible configuration files found:" echo "$configs" | nl -w2 -s') ' # If exactly one file is found, offer it local count=$(echo "$configs" | wc -l) if [ "$count" -eq 1 ]; then echo "[Question] Configuration file found. Use it?" read -p "Use $(echo "$configs" | tr -d '\n')? (y/n) " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then CONFIG_PATH=$(echo "$configs" | head -1) return 0 fi fi # If multiple files or user refused echo "[Input] Please specify the path to the configuration file manually:" read -p "Path to config: " user_path if [ -n "$user_path" ]; then if docker exec "$container" test -f "$user_path" 2>/dev/null; then CONFIG_PATH="$user_path" return 0 else echo " [ERR] File not found: ${user_path}" fi fi fi return 1 } # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Check for the first argument if [ -z "$1" ]; then echo -e "${RED}[ERR] Error: container name not specified${NC}" echo "" show_help exit 1 fi CONTAINER_NAME="$1" CONFIG_PATH="" # Will be determined later # Check if container exists (in any state) if ! docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then echo -e "${RED}[ERR] Error: container '${CONTAINER_NAME}' not found${NC}" echo "" echo -e "${YELLOW}[List] Available containers:${NC}" docker ps -a --format "table {{.Names}}\t{{.Status}}\t{{.Image}}" | head -10 echo "" show_help exit 1 fi # Check if container is running CONTAINER_STATUS=$(docker inspect --format='{{.State.Status}}' "$CONTAINER_NAME" 2>/dev/null) if [ "$CONTAINER_STATUS" != "running" ]; then echo -e "${RED}[ERR] Error: container '${CONTAINER_NAME}' not running${NC}" echo -e "${YELLOW}[Status] Current status: ${CONTAINER_STATUS}${NC}" echo "" echo -e "${BLUE}[Hint] You can start the container with the command:${NC}" echo " docker start $CONTAINER_NAME" exit 1 fi # Determine path to configuration file if [ -n "$2" ]; then # If path is specified explicitly, check it echo "[Search] Checking specified path: ${2}" if docker exec "$CONTAINER_NAME" test -f "$2" 2>/dev/null; then CONFIG_PATH="$2" echo " [OK] Configuration file found" else echo -e "${RED} [ERR] Specified file not found: ${2}${NC}" echo -e "${YELLOW}[Warning] Trying to find automatically...${NC}" fi fi # If path is not determined, try to find automatically if [ -z "$CONFIG_PATH" ]; then if ! find_config "$CONTAINER_NAME" "$2"; then echo -e "${YELLOW}[Warning] Could not find configuration file in standard paths${NC}" # Offer extended search read -p "[Search] Perform extended search for configuration files? (y/n) " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then if ! find_all_configs "$CONTAINER_NAME"; then echo -e "${RED}[ERR] Error: Could not find configuration file${NC}" exit 1 fi else echo -e "${RED}[ERR] Operation canceled${NC}" exit 1 fi fi fi echo -e "${GREEN}[OK] All checks passed${NC}" echo "[Info] Using config: ${CONFIG_PATH}" echo "[Start] Running garbage collector in container '${CONTAINER_NAME}'..." # Execute garbage collector if docker exec "$CONTAINER_NAME" registry garbage-collect "$CONFIG_PATH"; then echo -e "${GREEN}[OK] Garbage collector executed successfully${NC}" else echo -e "${RED}[ERR] Error executing garbage collector${NC}" echo -e "${YELLOW}[Possible causes]:${NC}" echo " - Insufficient permissions in container" echo " - Incorrect path to configuration file" echo " - Registry issues" exit 1 fi # Restart container echo "[Restart] Restarting container..." if docker restart "$CONTAINER_NAME"; then echo -e "${GREEN}[OK] Container successfully restarted${NC}" else echo -e "${RED}[ERR] Error restarting container${NC}" exit 1 fi echo -e "${GREEN}[OK] DONE! Garbage collector completed, container restarted${NC}" # Show container status echo "[Status] Current container status:" docker ps --filter "name=$CONTAINER_NAME" --format "table {{.Names}}\t{{.Status}}\t{{.RunningFor}}" | tail -n +2 # Show configuration file used echo "[Info] Configuration file used: ${CONFIG_PATH}"