459 lines
No EOL
16 KiB
Bash
Executable file
459 lines
No EOL
16 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
# =========================================================================
|
|
# fix-db-connection.sh
|
|
# =========================================================================
|
|
# Description: This script checks and fixes database connection issues on the
|
|
# staging server that are causing E2E test failures. It specifically addresses
|
|
# the "Access denied for user 'root'@'localhost'" error by verifying and
|
|
# correcting database configuration settings in local scripts and configurations.
|
|
#
|
|
# Usage: ./bin/fix-db-connection.sh [--verbose] [--dry-run]
|
|
#
|
|
# Options:
|
|
# --verbose Show detailed output during execution
|
|
# --dry-run Show what would be done without making changes
|
|
#
|
|
# Author: Roo Code
|
|
# Date: April 24, 2025
|
|
# =========================================================================
|
|
|
|
# Get absolute path to this script's directory
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
# Load environment variables
|
|
ENV_FILE="$SCRIPT_DIR/../.env"
|
|
if [ ! -f "$ENV_FILE" ]; then
|
|
echo "Error: .env file not found at: $ENV_FILE"
|
|
exit 1
|
|
fi
|
|
|
|
source "$ENV_FILE"
|
|
|
|
# Colors for output
|
|
GREEN='\033[0;32m'
|
|
RED='\033[0;31m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
# Default options
|
|
VERBOSE=false
|
|
DRY_RUN=false
|
|
|
|
# Parse command line arguments
|
|
for arg in "$@"; do
|
|
case $arg in
|
|
--verbose)
|
|
VERBOSE=true
|
|
shift
|
|
;;
|
|
--dry-run)
|
|
DRY_RUN=true
|
|
shift
|
|
;;
|
|
--help)
|
|
echo "Usage: $0 [--verbose] [--dry-run]"
|
|
echo ""
|
|
echo "Options:"
|
|
echo " --verbose Show detailed output during execution"
|
|
echo " --dry-run Show what would be done without making changes"
|
|
echo " --help Show this help message"
|
|
exit 0
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Function to check if a command was successful
|
|
check_status() {
|
|
if [ $? -eq 0 ]; then
|
|
echo -e "${GREEN}✓ $1${NC}"
|
|
return 0
|
|
else
|
|
echo -e "${RED}✗ $1${NC}"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Function to log verbose output
|
|
log_verbose() {
|
|
if [ "$VERBOSE" = true ]; then
|
|
echo -e "${BLUE}[INFO] $1${NC}"
|
|
fi
|
|
}
|
|
|
|
# Function to log error messages
|
|
log_error() {
|
|
echo -e "${RED}[ERROR] $1${NC}"
|
|
}
|
|
|
|
# Function to log warning messages
|
|
log_warning() {
|
|
echo -e "${YELLOW}[WARNING] $1${NC}"
|
|
}
|
|
|
|
# Function to log success messages
|
|
log_success() {
|
|
echo -e "${GREEN}[SUCCESS] $1${NC}"
|
|
}
|
|
|
|
# Function to check SSH connection
|
|
check_ssh_connection() {
|
|
log_verbose "Testing SSH connection to staging server..."
|
|
if ! sshpass -p "$UPSKILL_STAGING_PASS" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 "$UPSKILL_STAGING_SSH_USER@$UPSKILL_STAGING_IP" "echo 'SSH connection successful'" > /dev/null 2>&1; then
|
|
log_error "Cannot connect to staging server. Please check your SSH credentials and network connection."
|
|
exit 1
|
|
fi
|
|
log_verbose "SSH connection successful."
|
|
}
|
|
|
|
# Function to check database connection from staging server
|
|
check_remote_db_connection() {
|
|
log_verbose "Testing database connection from staging server..."
|
|
|
|
# Construct the MySQL command to run on the staging server
|
|
local mysql_cmd="mysql -h localhost -u $UPSKILL_STAGING_DB_USER -p'$UPSKILL_STAGING_DB_PASSWORD' $UPSKILL_STAGING_DB_NAME -e 'SELECT 1;' 2>&1"
|
|
|
|
# Execute the command on the staging server
|
|
local result
|
|
result=$(sshpass -p "$UPSKILL_STAGING_PASS" ssh -o StrictHostKeyChecking=no "$UPSKILL_STAGING_SSH_USER@$UPSKILL_STAGING_IP" "$mysql_cmd")
|
|
|
|
# Check if the command was successful
|
|
if [[ $result == *"1"* ]]; then
|
|
log_success "Database connection from staging server successful."
|
|
return 0
|
|
else
|
|
log_error "Database connection from staging server failed: $result"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Function to check database connection from local machine
|
|
check_local_db_connection() {
|
|
log_verbose "Testing database connection from local machine..."
|
|
|
|
# Construct the MySQL command to run locally
|
|
local mysql_cmd="mysql -h $UPSKILL_STAGING_IP -u $UPSKILL_STAGING_DB_USER -p'$UPSKILL_STAGING_DB_PASSWORD' $UPSKILL_STAGING_DB_NAME -e 'SELECT 1;' 2>&1"
|
|
|
|
# Execute the command locally
|
|
local result
|
|
result=$(eval "$mysql_cmd")
|
|
|
|
# Check if the command was successful
|
|
if [[ $result == *"1"* ]]; then
|
|
log_success "Database connection from local machine successful."
|
|
return 0
|
|
else
|
|
log_warning "Database connection from local machine failed: $result"
|
|
log_verbose "This is expected if the database is not accessible from outside the server."
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Function to check WordPress database configuration
|
|
check_wp_config() {
|
|
log_verbose "Checking WordPress database configuration on staging server..."
|
|
|
|
# Get the database configuration from wp-config.php
|
|
local wp_config_cmd="cd $UPSKILL_STAGING_PATH && grep -E \"^define\\('DB_[A-Z]+', '.*'\\);\" wp-config.php"
|
|
local wp_config
|
|
wp_config=$(sshpass -p "$UPSKILL_STAGING_PASS" ssh -o StrictHostKeyChecking=no "$UPSKILL_STAGING_SSH_USER@$UPSKILL_STAGING_IP" "$wp_config_cmd")
|
|
|
|
# Extract database settings
|
|
local db_name=$(echo "$wp_config" | grep "DB_NAME" | sed -E "s/define\('DB_NAME', '(.*)'\);/\1/")
|
|
local db_user=$(echo "$wp_config" | grep "DB_USER" | sed -E "s/define\('DB_USER', '(.*)'\);/\1/")
|
|
local db_password=$(echo "$wp_config" | grep "DB_PASSWORD" | sed -E "s/define\('DB_PASSWORD', '(.*)'\);/\1/")
|
|
local db_host=$(echo "$wp_config" | grep "DB_HOST" | sed -E "s/define\('DB_HOST', '(.*)'\);/\1/")
|
|
|
|
echo "Current WordPress database configuration on staging server:"
|
|
echo " DB_NAME: $db_name"
|
|
echo " DB_USER: $db_user"
|
|
echo " DB_HOST: $db_host"
|
|
echo " DB_PASSWORD: [HIDDEN]"
|
|
|
|
# Check if the configuration matches the environment variables
|
|
if [ "$db_name" != "$UPSKILL_STAGING_DB_NAME" ]; then
|
|
log_warning "DB_NAME in wp-config.php ($db_name) does not match .env file ($UPSKILL_STAGING_DB_NAME)"
|
|
fi
|
|
|
|
if [ "$db_user" != "$UPSKILL_STAGING_DB_USER" ]; then
|
|
log_warning "DB_USER in wp-config.php ($db_user) does not match .env file ($UPSKILL_STAGING_DB_USER)"
|
|
fi
|
|
|
|
if [ "$db_password" != "$UPSKILL_STAGING_DB_PASSWORD" ]; then
|
|
log_warning "DB_PASSWORD in wp-config.php does not match .env file"
|
|
fi
|
|
|
|
# Return the extracted values
|
|
echo "$db_name|$db_user|$db_password|$db_host"
|
|
}
|
|
|
|
# Function to check for hardcoded database credentials in test files
|
|
check_test_files() {
|
|
log_verbose "Checking for hardcoded database credentials in test files..."
|
|
|
|
# Search for 'root' user in test files
|
|
local search_cmd="find $SCRIPT_DIR/.. -type f -name \"*.php\" -o -name \"*.js\" -o -name \"*.ts\" | xargs grep -l \"'root'\\|\\\"root\\\"\" 2>/dev/null || true"
|
|
local files
|
|
files=$(eval "$search_cmd")
|
|
|
|
if [ -n "$files" ]; then
|
|
echo "Found files with potential hardcoded 'root' database user:"
|
|
echo "$files"
|
|
return 0
|
|
else
|
|
log_verbose "No files with hardcoded 'root' database user found."
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Function to check Playwright configuration
|
|
check_playwright_config() {
|
|
log_verbose "Checking Playwright configuration..."
|
|
|
|
local config_file="$SCRIPT_DIR/../playwright.config.ts"
|
|
|
|
if [ ! -f "$config_file" ]; then
|
|
log_warning "Playwright configuration file not found: $config_file"
|
|
return 1
|
|
fi
|
|
|
|
# Check for database configuration in Playwright config
|
|
local db_config
|
|
db_config=$(grep -A 10 "database\|DB_" "$config_file" 2>/dev/null || true)
|
|
|
|
if [ -n "$db_config" ]; then
|
|
echo "Found database configuration in Playwright config:"
|
|
echo "$db_config"
|
|
return 0
|
|
else
|
|
log_verbose "No database configuration found in Playwright config."
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Function to check E2E test files for database connection issues
|
|
check_e2e_tests() {
|
|
log_verbose "Checking E2E test files for database connection issues..."
|
|
|
|
local tests_dir="$SCRIPT_DIR/../tests"
|
|
|
|
if [ ! -d "$tests_dir" ]; then
|
|
log_warning "Tests directory not found: $tests_dir"
|
|
return 1
|
|
fi
|
|
|
|
# Search for database connection code in E2E test files
|
|
local search_cmd="find $tests_dir -type f -name \"*.spec.ts\" -o -name \"*.spec.js\" | xargs grep -l \"mysql\\|database\\|connection\\|root\" 2>/dev/null || true"
|
|
local files
|
|
files=$(eval "$search_cmd")
|
|
|
|
if [ -n "$files" ]; then
|
|
echo "Found E2E test files with potential database connection code:"
|
|
echo "$files"
|
|
return 0
|
|
else
|
|
log_verbose "No E2E test files with database connection code found."
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Function to fix database connection in a file
|
|
fix_file() {
|
|
local file="$1"
|
|
local backup_file="${file}.bak.$(date +%Y%m%d%H%M%S)"
|
|
|
|
log_verbose "Fixing database connection in file: $file"
|
|
|
|
# Create a backup of the file
|
|
if [ "$DRY_RUN" = true ]; then
|
|
log_verbose "Would create backup of $file to $backup_file"
|
|
else
|
|
cp "$file" "$backup_file"
|
|
check_status "Created backup of $file"
|
|
fi
|
|
|
|
# Replace 'root' with the correct database user
|
|
if [ "$DRY_RUN" = true ]; then
|
|
log_verbose "Would replace 'root' with '$UPSKILL_STAGING_DB_USER' in $file"
|
|
else
|
|
sed -i.tmp "s/'root'/'$UPSKILL_STAGING_DB_USER'/g" "$file"
|
|
sed -i.tmp "s/\"root\"/\"$UPSKILL_STAGING_DB_USER\"/g" "$file"
|
|
rm -f "${file}.tmp"
|
|
check_status "Replaced 'root' with '$UPSKILL_STAGING_DB_USER' in $file"
|
|
fi
|
|
|
|
# Replace hardcoded password if found
|
|
if [ "$DRY_RUN" = true ]; then
|
|
log_verbose "Would replace hardcoded password with '$UPSKILL_STAGING_DB_PASSWORD' in $file"
|
|
else
|
|
# This is a simplified approach; in a real scenario, you'd need a more sophisticated pattern matching
|
|
sed -i.tmp "s/'password'/'$UPSKILL_STAGING_DB_PASSWORD'/g" "$file"
|
|
sed -i.tmp "s/\"password\"/\"$UPSKILL_STAGING_DB_PASSWORD\"/g" "$file"
|
|
rm -f "${file}.tmp"
|
|
check_status "Replaced hardcoded password in $file"
|
|
fi
|
|
}
|
|
|
|
# Function to check and fix wp-tests-config.php
|
|
check_wp_tests_config() {
|
|
log_verbose "Checking wp-tests-config.php..."
|
|
|
|
local config_file="$SCRIPT_DIR/../wp-tests-config.php"
|
|
|
|
if [ ! -f "$config_file" ]; then
|
|
log_warning "wp-tests-config.php not found: $config_file"
|
|
return 1
|
|
fi
|
|
|
|
# Check for 'root' user in wp-tests-config.php
|
|
local root_user
|
|
root_user=$(grep -E "define\\( *'DB_USER', *'root' *\\)" "$config_file" 2>/dev/null || true)
|
|
|
|
if [ -n "$root_user" ]; then
|
|
echo "Found 'root' user in wp-tests-config.php:"
|
|
echo "$root_user"
|
|
|
|
# Fix wp-tests-config.php
|
|
if [ "$DRY_RUN" = true ]; then
|
|
log_verbose "Would update wp-tests-config.php to use '$UPSKILL_STAGING_DB_USER' instead of 'root'"
|
|
else
|
|
local backup_file="${config_file}.bak.$(date +%Y%m%d%H%M%S)"
|
|
cp "$config_file" "$backup_file"
|
|
sed -i.tmp "s/define( *'DB_USER', *'root' *)/define( 'DB_USER', '$UPSKILL_STAGING_DB_USER' )/g" "$config_file"
|
|
sed -i.tmp "s/define( *'DB_PASSWORD', *'[^']*' *)/define( 'DB_PASSWORD', '$UPSKILL_STAGING_DB_PASSWORD' )/g" "$config_file"
|
|
rm -f "${config_file}.tmp"
|
|
check_status "Updated wp-tests-config.php to use correct database credentials"
|
|
fi
|
|
return 0
|
|
else
|
|
log_verbose "No 'root' user found in wp-tests-config.php."
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Function to check and fix wp-tests-config-staging.php
|
|
check_wp_tests_config_staging() {
|
|
log_verbose "Checking wp-tests-config-staging.php..."
|
|
|
|
local config_file="$SCRIPT_DIR/wp-tests-config-staging.php"
|
|
|
|
if [ ! -f "$config_file" ]; then
|
|
log_warning "wp-tests-config-staging.php not found: $config_file"
|
|
return 1
|
|
fi
|
|
|
|
# Check for 'root' user in wp-tests-config-staging.php
|
|
local root_user
|
|
root_user=$(grep -E "define\\( *'DB_USER', *'root' *\\)" "$config_file" 2>/dev/null || true)
|
|
|
|
if [ -n "$root_user" ]; then
|
|
echo "Found 'root' user in wp-tests-config-staging.php:"
|
|
echo "$root_user"
|
|
|
|
# Fix wp-tests-config-staging.php
|
|
if [ "$DRY_RUN" = true ]; then
|
|
log_verbose "Would update wp-tests-config-staging.php to use '$UPSKILL_STAGING_DB_USER' instead of 'root'"
|
|
else
|
|
local backup_file="${config_file}.bak.$(date +%Y%m%d%H%M%S)"
|
|
cp "$config_file" "$backup_file"
|
|
sed -i.tmp "s/define( *'DB_USER', *'root' *)/define( 'DB_USER', '$UPSKILL_STAGING_DB_USER' )/g" "$config_file"
|
|
sed -i.tmp "s/define( *'DB_PASSWORD', *'[^']*' *)/define( 'DB_PASSWORD', '$UPSKILL_STAGING_DB_PASSWORD' )/g" "$config_file"
|
|
rm -f "${config_file}.tmp"
|
|
check_status "Updated wp-tests-config-staging.php to use correct database credentials"
|
|
fi
|
|
return 0
|
|
else
|
|
log_verbose "No 'root' user found in wp-tests-config-staging.php."
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Main function
|
|
main() {
|
|
echo "=== Database Connection Fix Script ==="
|
|
echo "Staging Server: $UPSKILL_STAGING_IP"
|
|
echo "Database: $UPSKILL_STAGING_DB_NAME"
|
|
echo "User: $UPSKILL_STAGING_DB_USER"
|
|
echo "==============================="
|
|
|
|
if [ "$DRY_RUN" = true ]; then
|
|
echo -e "${YELLOW}Running in dry-run mode. No changes will be made.${NC}"
|
|
fi
|
|
|
|
# Step 1: Check SSH connection
|
|
echo -e "\n${YELLOW}Step 1: Checking SSH connection...${NC}"
|
|
check_ssh_connection
|
|
check_status "SSH connection check"
|
|
|
|
# Step 2: Check remote database connection
|
|
echo -e "\n${YELLOW}Step 2: Checking database connection from staging server...${NC}"
|
|
check_remote_db_connection
|
|
check_status "Remote database connection check"
|
|
|
|
# Step 3: Check WordPress configuration
|
|
echo -e "\n${YELLOW}Step 3: Checking WordPress configuration...${NC}"
|
|
check_wp_config
|
|
check_status "WordPress configuration check"
|
|
|
|
# Step 4: Check test files for hardcoded credentials
|
|
echo -e "\n${YELLOW}Step 4: Checking test files for hardcoded credentials...${NC}"
|
|
if check_test_files; then
|
|
echo "Found files with potential hardcoded credentials. Fixing..."
|
|
|
|
# Fix each file
|
|
for file in $(find $SCRIPT_DIR/.. -type f -name "*.php" -o -name "*.js" -o -name "*.ts" | xargs grep -l "'root'\\|\"root\"" 2>/dev/null || true); do
|
|
fix_file "$file"
|
|
done
|
|
else
|
|
echo "No files with hardcoded 'root' credentials found."
|
|
fi
|
|
|
|
# Step 5: Check and fix wp-tests-config.php
|
|
echo -e "\n${YELLOW}Step 5: Checking and fixing wp-tests-config.php...${NC}"
|
|
check_wp_tests_config
|
|
|
|
# Step 6: Check and fix wp-tests-config-staging.php
|
|
echo -e "\n${YELLOW}Step 6: Checking and fixing wp-tests-config-staging.php...${NC}"
|
|
check_wp_tests_config_staging
|
|
|
|
# Step 7: Check Playwright configuration
|
|
echo -e "\n${YELLOW}Step 7: Checking Playwright configuration...${NC}"
|
|
check_playwright_config
|
|
|
|
# Step 8: Check E2E test files
|
|
echo -e "\n${YELLOW}Step 8: Checking E2E test files...${NC}"
|
|
check_e2e_tests
|
|
|
|
# Step 9: Verify fixes
|
|
echo -e "\n${YELLOW}Step 9: Verifying fixes...${NC}"
|
|
if [ "$DRY_RUN" = false ]; then
|
|
# Check remote database connection again
|
|
check_remote_db_connection
|
|
check_status "Remote database connection verification"
|
|
|
|
# Run a simple E2E test if available
|
|
if [ -f "$SCRIPT_DIR/../node_modules/.bin/playwright" ]; then
|
|
echo "Running a simple Playwright test to verify database connection..."
|
|
cd "$SCRIPT_DIR/.." && npx playwright test -g "database connection" --headed
|
|
check_status "Playwright test"
|
|
else
|
|
log_warning "Playwright not found. Skipping E2E test verification."
|
|
fi
|
|
else
|
|
echo -e "${YELLOW}Skipping verification in dry-run mode.${NC}"
|
|
fi
|
|
|
|
# Summary
|
|
echo -e "\n${YELLOW}Summary:${NC}"
|
|
if [ "$DRY_RUN" = true ]; then
|
|
echo "Dry run completed. No changes were made."
|
|
echo "Run the script without --dry-run to apply the fixes."
|
|
else
|
|
echo "Database connection fix script completed."
|
|
echo "If you encounter any issues, you can restore the backup files created during the fix process."
|
|
fi
|
|
}
|
|
|
|
# Run the main function
|
|
main |