cbe6cb24f1
These scripts are now comprehensive discovery tools that:
1. Actually TEST operations (not just detect)
2. Document complete system knowledge for future reference
CRITICAL NEW TESTS:
Plesk validator (validate-plesk.sh):
• NEW TEST 8: File ownership detection + cron user determination
- Checks who owns document root files
- Determines correct user for cron jobs
- ANSWERS: Should we use www-data, owner, or domain-specific user?
• ENHANCED TEST 9: Cron system operational testing
- Actually WRITES test cron entry (then removes it)
- Tests both standard crontab AND plesk bin cron
- ANSWERS: Which cron system actually works?
• NEW TEST 13: WordPress file permissions & wp-config.php access
- Tests if we can read wp-config.php
- Extracts database credentials
- Determines database prefix pattern from REAL data
• NEW TEST 14: Comprehensive system documentation
- Catalogs ALL Plesk bin commands
- Lists ALL domains on system
- Documents ALL PHP versions
- Records web server config (nginx + Apache detection)
- Creates "QUICK REFERENCE FOR DEVELOPERS" section
InterWorx validator (validate-interworx.sh):
• NEW TEST 11: WordPress file permissions & cron user testing
- Extracts database name from wp-config.php
- VERIFIES username_ database prefix from real data
- Actually WRITES test cron entry (then removes it)
- ANSWERS: Can we use crontab -u USER for cron jobs?
• NEW TEST 12: Comprehensive system documentation
- Catalogs ALL InterWorx bin commands
- Lists ALL users on system
- Lists ALL vhost configurations
- Documents sample vhost config structure
- Creates "QUICK REFERENCE FOR DEVELOPERS" section
WHAT THESE SCRIPTS NOW ANSWER:
Plesk - CRITICAL BLOCKERS:
✓ Who owns web files? (determines cron user)
✓ Can we write crontab entries?
✓ What's the database prefix pattern? (from real wp-config.php)
✓ Which cron system to use?
✓ All available Plesk commands
✓ Complete system inventory
InterWorx - VERIFICATION:
✓ Confirms username_ database prefix (from real data)
✓ Confirms crontab -u USER works
✓ Documents all InterWorx commands
✓ Complete system inventory
OUTPUT FORMAT:
Both scripts now generate comprehensive results files with:
- Color-coded test results (PASS/FAIL/WARN)
- Complete system documentation
- Quick reference guide for developers
- Actionable answers to critical questions
These scripts will learn EVERYTHING we need to know in one run!
871 lines
32 KiB
Bash
Executable File
871 lines
32 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
################################################################################
|
|
# Plesk Validation Script
|
|
# Purpose: Verify all assumptions about Plesk file system, commands, and paths
|
|
# Run this on a real Plesk server to validate our refactoring
|
|
################################################################################
|
|
|
|
set -e
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
RESULTS_FILE="/tmp/plesk-validation-results.txt"
|
|
|
|
# Color output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Counters
|
|
PASS=0
|
|
FAIL=0
|
|
WARN=0
|
|
|
|
echo "======================================================================="
|
|
echo "PLESK VALIDATION SCRIPT"
|
|
echo "======================================================================="
|
|
echo "This script will verify all assumptions about Plesk"
|
|
echo "Results will be saved to: $RESULTS_FILE"
|
|
echo ""
|
|
echo "Started: $(date)"
|
|
echo "======================================================================="
|
|
echo ""
|
|
|
|
# Initialize results file
|
|
cat > "$RESULTS_FILE" <<EOF
|
|
Plesk Validation Results
|
|
Generated: $(date)
|
|
Hostname: $(hostname)
|
|
EOF
|
|
|
|
################################################################################
|
|
# Helper Functions
|
|
################################################################################
|
|
|
|
test_pass() {
|
|
echo -e "${GREEN}[PASS]${NC} $1"
|
|
echo "[PASS] $1" >> "$RESULTS_FILE"
|
|
((PASS++))
|
|
}
|
|
|
|
test_fail() {
|
|
echo -e "${RED}[FAIL]${NC} $1"
|
|
echo "[FAIL] $1" >> "$RESULTS_FILE"
|
|
((FAIL++))
|
|
}
|
|
|
|
test_warn() {
|
|
echo -e "${YELLOW}[WARN]${NC} $1"
|
|
echo "[WARN] $1" >> "$RESULTS_FILE"
|
|
((WARN++))
|
|
}
|
|
|
|
test_info() {
|
|
echo -e "${BLUE}[INFO]${NC} $1"
|
|
echo "[INFO] $1" >> "$RESULTS_FILE"
|
|
}
|
|
|
|
section_header() {
|
|
echo ""
|
|
echo "======================================================================="
|
|
echo "$1"
|
|
echo "======================================================================="
|
|
echo "" >> "$RESULTS_FILE"
|
|
echo "=======================================================================" >> "$RESULTS_FILE"
|
|
echo "$1" >> "$RESULTS_FILE"
|
|
echo "=======================================================================" >> "$RESULTS_FILE"
|
|
}
|
|
|
|
################################################################################
|
|
# TEST 1: Control Panel Detection
|
|
################################################################################
|
|
|
|
section_header "TEST 1: Control Panel Detection"
|
|
|
|
if [ -d "/usr/local/psa" ]; then
|
|
test_pass "Plesk installation directory exists: /usr/local/psa"
|
|
else
|
|
test_fail "Plesk installation directory NOT found: /usr/local/psa"
|
|
fi
|
|
|
|
if command -v plesk &> /dev/null; then
|
|
test_pass "plesk command available"
|
|
|
|
# Get Plesk version
|
|
PLESK_VERSION=$(plesk version 2>/dev/null | head -1)
|
|
test_info "Plesk version: $PLESK_VERSION"
|
|
else
|
|
test_fail "plesk command not available"
|
|
fi
|
|
|
|
################################################################################
|
|
# TEST 2: File System Structure
|
|
################################################################################
|
|
|
|
section_header "TEST 2: File System Structure"
|
|
|
|
# Check main vhosts directory
|
|
if [ -d "/var/www/vhosts" ]; then
|
|
test_pass "Main vhosts directory exists: /var/www/vhosts"
|
|
|
|
# Find a test domain
|
|
TEST_DOMAIN=""
|
|
for domain_dir in /var/www/vhosts/*; do
|
|
domain=$(basename "$domain_dir")
|
|
# Skip system directories
|
|
if [[ "$domain" != "system" ]] && [[ "$domain" != "default" ]] && [[ "$domain" != "chroot" ]] && [[ -d "$domain_dir/httpdocs" ]]; then
|
|
TEST_DOMAIN="$domain"
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [ -n "$TEST_DOMAIN" ]; then
|
|
test_pass "Found test domain: $TEST_DOMAIN"
|
|
|
|
# Test document root path
|
|
EXPECTED_DOCROOT="/var/www/vhosts/$TEST_DOMAIN/httpdocs"
|
|
if [ -d "$EXPECTED_DOCROOT" ]; then
|
|
test_pass "Document root exists: $EXPECTED_DOCROOT"
|
|
test_pass "VERIFIED: Document root pattern is /var/www/vhosts/DOMAIN/httpdocs"
|
|
else
|
|
test_fail "Document root NOT found: $EXPECTED_DOCROOT"
|
|
fi
|
|
|
|
# Test domain root structure
|
|
test_info "Domain root structure for $TEST_DOMAIN:"
|
|
ls -la "/var/www/vhosts/$TEST_DOMAIN" | head -20 >> "$RESULTS_FILE" 2>&1
|
|
|
|
else
|
|
test_warn "No test domain found in /var/www/vhosts"
|
|
test_info "Available directories:"
|
|
ls -d /var/www/vhosts/*/ 2>/dev/null | head -10 >> "$RESULTS_FILE"
|
|
fi
|
|
|
|
else
|
|
test_fail "Main vhosts directory NOT found: /var/www/vhosts"
|
|
fi
|
|
|
|
################################################################################
|
|
# TEST 3: Log File Locations
|
|
################################################################################
|
|
|
|
section_header "TEST 3: Log File Locations"
|
|
|
|
if [ -d "/var/www/vhosts/system" ]; then
|
|
test_pass "System logs directory exists: /var/www/vhosts/system"
|
|
|
|
if [ -n "$TEST_DOMAIN" ]; then
|
|
# Test access log path
|
|
EXPECTED_ACCESS_LOG="/var/www/vhosts/system/$TEST_DOMAIN/logs/access_log"
|
|
if [ -f "$EXPECTED_ACCESS_LOG" ]; then
|
|
test_pass "Access log exists: $EXPECTED_ACCESS_LOG"
|
|
test_pass "VERIFIED: Access log pattern is /var/www/vhosts/system/DOMAIN/logs/access_log"
|
|
else
|
|
test_warn "Access log NOT found: $EXPECTED_ACCESS_LOG (may not have traffic yet)"
|
|
fi
|
|
|
|
# Test SSL access log path
|
|
EXPECTED_SSL_LOG="/var/www/vhosts/system/$TEST_DOMAIN/logs/access_ssl_log"
|
|
if [ -f "$EXPECTED_SSL_LOG" ]; then
|
|
test_pass "SSL access log exists: $EXPECTED_SSL_LOG"
|
|
else
|
|
test_warn "SSL access log NOT found (may not have SSL traffic)"
|
|
fi
|
|
|
|
# Test error log path
|
|
EXPECTED_ERROR_LOG="/var/www/vhosts/system/$TEST_DOMAIN/logs/error_log"
|
|
if [ -f "$EXPECTED_ERROR_LOG" ]; then
|
|
test_pass "Error log exists: $EXPECTED_ERROR_LOG"
|
|
test_pass "VERIFIED: Error log pattern is /var/www/vhosts/system/DOMAIN/logs/error_log"
|
|
else
|
|
test_warn "Error log NOT found: $EXPECTED_ERROR_LOG (may not have errors yet)"
|
|
fi
|
|
|
|
# List all log files
|
|
LOG_DIR="/var/www/vhosts/system/$TEST_DOMAIN/logs"
|
|
if [ -d "$LOG_DIR" ]; then
|
|
test_info "Log files found:"
|
|
ls -lh "$LOG_DIR" >> "$RESULTS_FILE" 2>&1
|
|
fi
|
|
|
|
fi
|
|
|
|
else
|
|
test_fail "System logs directory NOT found: /var/www/vhosts/system"
|
|
fi
|
|
|
|
# Check for domain-level error logs (PHP errors)
|
|
if [ -n "$TEST_DOMAIN" ]; then
|
|
PHP_ERROR_LOG="/var/www/vhosts/$TEST_DOMAIN/httpdocs/error_log"
|
|
if [ -f "$PHP_ERROR_LOG" ]; then
|
|
test_pass "PHP error log exists in httpdocs: $PHP_ERROR_LOG"
|
|
else
|
|
test_warn "PHP error log not found in httpdocs (may not have PHP errors)"
|
|
fi
|
|
fi
|
|
|
|
################################################################################
|
|
# TEST 4: Plesk bin Commands
|
|
################################################################################
|
|
|
|
section_header "TEST 4: Plesk bin Commands"
|
|
|
|
if [ -d "/usr/local/psa/bin" ]; then
|
|
test_pass "Plesk bin directory exists: /usr/local/psa/bin"
|
|
test_info "Available Plesk bin commands:"
|
|
ls /usr/local/psa/bin | head -20 >> "$RESULTS_FILE"
|
|
else
|
|
test_fail "Plesk bin directory NOT found"
|
|
fi
|
|
|
|
# Test subscription command
|
|
if command -v plesk &> /dev/null; then
|
|
if plesk bin subscription --help &> /dev/null; then
|
|
test_pass "plesk bin subscription command available"
|
|
else
|
|
test_fail "plesk bin subscription command not working"
|
|
fi
|
|
fi
|
|
|
|
################################################################################
|
|
# TEST 5: Domain → User Mapping
|
|
################################################################################
|
|
|
|
section_header "TEST 5: Domain → User Mapping (Owner Lookup)"
|
|
|
|
if [ -n "$TEST_DOMAIN" ]; then
|
|
test_info "Testing domain→user lookup for: $TEST_DOMAIN"
|
|
|
|
# Method: plesk bin subscription --info DOMAIN
|
|
SUBSCRIPTION_INFO=$(plesk bin subscription --info "$TEST_DOMAIN" 2>/dev/null)
|
|
|
|
if [ -n "$SUBSCRIPTION_INFO" ]; then
|
|
test_pass "Successfully retrieved subscription info for $TEST_DOMAIN"
|
|
|
|
# Look for Owner field
|
|
OWNER=$(echo "$SUBSCRIPTION_INFO" | grep -i "^Owner:" | awk '{print $2}')
|
|
if [ -n "$OWNER" ]; then
|
|
test_pass "Found Owner field: $OWNER"
|
|
test_pass "VERIFIED: Domain→User lookup works via: plesk bin subscription --info DOMAIN | grep Owner"
|
|
TEST_OWNER="$OWNER"
|
|
else
|
|
# Try Login field as alternative
|
|
OWNER=$(echo "$SUBSCRIPTION_INFO" | grep -i "^Login:" | awk '{print $2}')
|
|
if [ -n "$OWNER" ]; then
|
|
test_pass "Found Login field: $OWNER (alternative to Owner)"
|
|
TEST_OWNER="$OWNER"
|
|
else
|
|
test_fail "Could not find Owner or Login field in subscription info"
|
|
fi
|
|
fi
|
|
|
|
# Show sample output
|
|
test_info "Sample subscription info output:"
|
|
echo "$SUBSCRIPTION_INFO" | head -15 >> "$RESULTS_FILE"
|
|
|
|
else
|
|
test_fail "Could not retrieve subscription info for: $TEST_DOMAIN"
|
|
fi
|
|
|
|
else
|
|
test_warn "No test domain available for lookup test"
|
|
fi
|
|
|
|
################################################################################
|
|
# TEST 6: User → Domains Mapping
|
|
################################################################################
|
|
|
|
section_header "TEST 6: User → Domains Mapping (List User's Domains)"
|
|
|
|
if [ -n "$TEST_OWNER" ]; then
|
|
test_info "Testing user→domains lookup for owner: $TEST_OWNER"
|
|
|
|
# Method 1: plesk bin subscription --list -owner USERNAME
|
|
USER_DOMAINS=$(plesk bin subscription --list -owner "$TEST_OWNER" 2>/dev/null)
|
|
|
|
if [ -n "$USER_DOMAINS" ]; then
|
|
DOMAIN_COUNT=$(echo "$USER_DOMAINS" | wc -l)
|
|
test_pass "Method 1: plesk bin subscription --list -owner found $DOMAIN_COUNT domain(s)"
|
|
test_pass "VERIFIED: User→Domains lookup works via: plesk bin subscription --list -owner USERNAME"
|
|
test_info "Domains for owner $TEST_OWNER:"
|
|
echo "$USER_DOMAINS" >> "$RESULTS_FILE"
|
|
else
|
|
test_warn "Method 1: No domains found for owner $TEST_OWNER"
|
|
fi
|
|
|
|
# Method 2: From filesystem (alternative)
|
|
FS_DOMAINS=$(find /var/www/vhosts -maxdepth 1 -type d ! -name "system" ! -name "default" ! -name "chroot" ! -name "vhosts" 2>/dev/null | xargs -n1 basename | sort)
|
|
|
|
if [ -n "$FS_DOMAINS" ]; then
|
|
FS_COUNT=$(echo "$FS_DOMAINS" | wc -l)
|
|
test_info "Method 2: Found $FS_COUNT total domain(s) in filesystem (all users)"
|
|
test_info "All domains in /var/www/vhosts:"
|
|
echo "$FS_DOMAINS" | head -10 >> "$RESULTS_FILE"
|
|
fi
|
|
|
|
else
|
|
test_warn "No test owner available - skipping user→domains test"
|
|
fi
|
|
|
|
################################################################################
|
|
# TEST 7: Database Prefix Pattern
|
|
################################################################################
|
|
|
|
section_header "TEST 7: Database Prefix Pattern"
|
|
|
|
test_info "Checking database naming conventions..."
|
|
|
|
# Try to connect to MySQL/MariaDB
|
|
if command -v mysql &> /dev/null; then
|
|
# Try to get database list
|
|
DB_LIST=$(mysql -e "SHOW DATABASES;" 2>/dev/null | grep -v "Database\|information_schema\|performance_schema\|mysql\|sys")
|
|
|
|
if [ -n "$DB_LIST" ]; then
|
|
test_pass "Successfully connected to database and retrieved database list"
|
|
test_info "Sample databases:"
|
|
echo "$DB_LIST" | head -15 >> "$RESULTS_FILE"
|
|
|
|
# Check for prefix patterns
|
|
HAS_UNDERSCORES=$(echo "$DB_LIST" | grep "_" | wc -l)
|
|
NO_UNDERSCORES=$(echo "$DB_LIST" | grep -v "_" | wc -l)
|
|
|
|
test_info "Databases with underscores: $HAS_UNDERSCORES"
|
|
test_info "Databases without underscores: $NO_UNDERSCORES"
|
|
|
|
# Check if databases follow username_ pattern or no prefix
|
|
if [ $NO_UNDERSCORES -gt 0 ]; then
|
|
test_info "Found databases without underscores (suggests NO PREFIX pattern)"
|
|
test_info "Sample databases without prefix:"
|
|
echo "$DB_LIST" | grep -v "_" | grep -v "test" | head -5 >> "$RESULTS_FILE"
|
|
test_pass "DATABASE PREFIX PATTERN: Appears to use NO PREFIX (bare database names)"
|
|
else
|
|
test_warn "All databases have underscores - cannot determine prefix pattern"
|
|
fi
|
|
|
|
# Look for WordPress database pattern
|
|
WP_DBS=$(echo "$DB_LIST" | grep -E "wp_|wordpress|_wp")
|
|
if [ -n "$WP_DBS" ]; then
|
|
test_info "Found WordPress-like databases:"
|
|
echo "$WP_DBS" | head -5 >> "$RESULTS_FILE"
|
|
fi
|
|
|
|
else
|
|
test_warn "Could not retrieve database list (may need credentials)"
|
|
fi
|
|
else
|
|
test_warn "mysql command not found - cannot test database prefix"
|
|
fi
|
|
|
|
################################################################################
|
|
# TEST 8: System User for Web Processes & File Ownership
|
|
################################################################################
|
|
|
|
section_header "TEST 8: System User for Web Processes & File Ownership"
|
|
|
|
test_info "Checking what user runs web/PHP processes..."
|
|
|
|
# Check PHP-FPM processes
|
|
PHP_FPM_USERS=$(ps aux | grep "php-fpm" | grep -v "grep" | awk '{print $1}' | sort -u)
|
|
if [ -n "$PHP_FPM_USERS" ]; then
|
|
test_pass "Found PHP-FPM processes running as:"
|
|
echo "$PHP_FPM_USERS" >> "$RESULTS_FILE"
|
|
|
|
if echo "$PHP_FPM_USERS" | grep -q "www-data"; then
|
|
test_info "PHP-FPM uses www-data (Debian/Ubuntu pattern)"
|
|
WEB_USER="www-data"
|
|
elif echo "$PHP_FPM_USERS" | grep -q "apache"; then
|
|
test_info "PHP-FPM uses apache (RHEL/CentOS pattern)"
|
|
WEB_USER="apache"
|
|
else
|
|
test_info "PHP-FPM uses custom user(s)"
|
|
WEB_USER=$(echo "$PHP_FPM_USERS" | head -1)
|
|
fi
|
|
else
|
|
test_warn "No PHP-FPM processes found"
|
|
WEB_USER="www-data" # Default assumption
|
|
fi
|
|
|
|
# Check Apache processes
|
|
APACHE_USERS=$(ps aux | grep -E "httpd|apache2" | grep -v "grep\|root" | awk '{print $1}' | sort -u | head -5)
|
|
if [ -n "$APACHE_USERS" ]; then
|
|
test_pass "Found Apache processes running as:"
|
|
echo "$APACHE_USERS" >> "$RESULTS_FILE"
|
|
else
|
|
test_warn "No Apache processes found"
|
|
fi
|
|
|
|
# CRITICAL: Check file ownership of WordPress/web files
|
|
if [ -n "$TEST_DOMAIN" ]; then
|
|
DOCROOT="/var/www/vhosts/$TEST_DOMAIN/httpdocs"
|
|
if [ -d "$DOCROOT" ]; then
|
|
FILE_OWNER=$(stat -c '%U' "$DOCROOT" 2>/dev/null || stat -f '%Su' "$DOCROOT" 2>/dev/null)
|
|
FILE_GROUP=$(stat -c '%G' "$DOCROOT" 2>/dev/null || stat -f '%Sg' "$DOCROOT" 2>/dev/null)
|
|
|
|
if [ -n "$FILE_OWNER" ]; then
|
|
test_pass "Document root owner: $FILE_OWNER:$FILE_GROUP"
|
|
|
|
# Check if files are owned by web user or domain-specific user
|
|
if [ "$FILE_OWNER" = "$WEB_USER" ]; then
|
|
test_info "Files owned by web process user ($WEB_USER)"
|
|
test_pass "ANSWER: Use 'crontab -u $WEB_USER' for cron jobs"
|
|
CRON_USER="$WEB_USER"
|
|
elif [ "$FILE_OWNER" = "$TEST_OWNER" ]; then
|
|
test_info "Files owned by domain owner ($TEST_OWNER)"
|
|
test_pass "ANSWER: Use 'crontab -u $TEST_OWNER' for cron jobs"
|
|
CRON_USER="$TEST_OWNER"
|
|
else
|
|
test_warn "Files owned by different user: $FILE_OWNER (not web user or domain owner)"
|
|
test_info "ANSWER: Use 'crontab -u $FILE_OWNER' for cron jobs"
|
|
CRON_USER="$FILE_OWNER"
|
|
fi
|
|
|
|
# Test a sample file inside
|
|
if [ -f "$DOCROOT/index.php" ] || [ -f "$DOCROOT/index.html" ]; then
|
|
SAMPLE_FILE=$(find "$DOCROOT" -maxdepth 1 -type f -name "index.*" 2>/dev/null | head -1)
|
|
if [ -n "$SAMPLE_FILE" ]; then
|
|
SAMPLE_OWNER=$(stat -c '%U' "$SAMPLE_FILE" 2>/dev/null || stat -f '%Su' "$SAMPLE_FILE" 2>/dev/null)
|
|
test_info "Sample file owner: $SAMPLE_OWNER (file: $(basename "$SAMPLE_FILE"))"
|
|
fi
|
|
fi
|
|
else
|
|
test_fail "Could not determine file ownership"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
################################################################################
|
|
# TEST 9: Cron System (CRITICAL - Test Actual Operations!)
|
|
################################################################################
|
|
|
|
section_header "TEST 9: Cron System (CRITICAL - Test Actual Operations!)"
|
|
|
|
if command -v crontab &> /dev/null; then
|
|
test_pass "crontab command available"
|
|
|
|
# Check for plesk bin cron command
|
|
HAS_PLESK_CRON=0
|
|
if plesk bin cron --help &> /dev/null 2>&1; then
|
|
test_pass "plesk bin cron command available (Plesk custom cron management)"
|
|
HAS_PLESK_CRON=1
|
|
else
|
|
test_info "plesk bin cron not available - using standard cron"
|
|
fi
|
|
|
|
# Check standard cron directory
|
|
if [ -d "/var/spool/cron" ]; then
|
|
test_pass "Standard cron spool directory exists: /var/spool/cron"
|
|
test_info "Cron files found:"
|
|
ls -lh /var/spool/cron/ 2>/dev/null >> "$RESULTS_FILE"
|
|
elif [ -d "/var/spool/cron/crontabs" ]; then
|
|
test_pass "Standard cron spool directory exists: /var/spool/cron/crontabs"
|
|
test_info "Cron files found:"
|
|
ls -lh /var/spool/cron/crontabs/ 2>/dev/null >> "$RESULTS_FILE"
|
|
else
|
|
test_warn "Standard cron spool directory not found"
|
|
fi
|
|
|
|
# CRITICAL TEST: Try to read/write cron for different users
|
|
if [ -n "$CRON_USER" ]; then
|
|
test_info "CRITICAL TEST: Testing cron operations for user: $CRON_USER"
|
|
|
|
# Test 1: Can we read the crontab?
|
|
if crontab -u "$CRON_USER" -l &> /dev/null; then
|
|
test_pass "✓ CAN READ crontab for user: $CRON_USER"
|
|
test_info "Current crontab entries:"
|
|
crontab -u "$CRON_USER" -l 2>/dev/null >> "$RESULTS_FILE"
|
|
else
|
|
CRON_READ_ERR=$?
|
|
if [ $CRON_READ_ERR -eq 1 ]; then
|
|
test_info "User $CRON_USER has no crontab (this is OK - means empty)"
|
|
else
|
|
test_warn "Cannot read crontab for $CRON_USER (exit code: $CRON_READ_ERR)"
|
|
fi
|
|
fi
|
|
|
|
# Test 2: Can we write a test cron entry? (ACTUALLY TEST IT)
|
|
test_info "ATTEMPTING: Test cron write operation (will be immediately removed)..."
|
|
|
|
# Backup existing crontab
|
|
TEMP_BACKUP="/tmp/plesk_cron_backup_$$"
|
|
crontab -u "$CRON_USER" -l > "$TEMP_BACKUP" 2>/dev/null || echo "# No existing crontab" > "$TEMP_BACKUP"
|
|
|
|
# Try to add a test entry
|
|
TEST_CRON_ENTRY="# TEST ENTRY - Plesk Validation - Will be removed"
|
|
(crontab -u "$CRON_USER" -l 2>/dev/null; echo "$TEST_CRON_ENTRY") | crontab -u "$CRON_USER" - 2>/dev/null
|
|
|
|
if [ $? -eq 0 ]; then
|
|
test_pass "✓ CAN WRITE crontab for user: $CRON_USER"
|
|
test_pass "ANSWER: Standard crontab works - use 'crontab -u $CRON_USER'"
|
|
|
|
# Restore original crontab immediately
|
|
crontab -u "$CRON_USER" "$TEMP_BACKUP" 2>/dev/null
|
|
test_info "Test entry removed, original crontab restored"
|
|
else
|
|
test_fail "✗ CANNOT WRITE crontab for user: $CRON_USER"
|
|
test_warn "May need to use 'plesk bin cron' instead of standard crontab"
|
|
fi
|
|
|
|
rm -f "$TEMP_BACKUP"
|
|
fi
|
|
|
|
# Test plesk bin cron if available
|
|
if [ $HAS_PLESK_CRON -eq 1 ] && [ -n "$TEST_DOMAIN" ]; then
|
|
test_info "Testing Plesk cron management for domain: $TEST_DOMAIN"
|
|
|
|
# Try to list cron jobs via plesk
|
|
PLESK_CRONS=$(plesk bin cron -l -domain "$TEST_DOMAIN" 2>/dev/null)
|
|
if [ $? -eq 0 ]; then
|
|
test_pass "✓ Can list Plesk cron jobs for domain"
|
|
if [ -n "$PLESK_CRONS" ]; then
|
|
test_info "Plesk cron jobs found:"
|
|
echo "$PLESK_CRONS" | head -20 >> "$RESULTS_FILE"
|
|
else
|
|
test_info "No Plesk cron jobs configured for domain"
|
|
fi
|
|
else
|
|
test_warn "Cannot list Plesk cron jobs (may need different syntax)"
|
|
fi
|
|
fi
|
|
|
|
# Document which method to use
|
|
echo "" >> "$RESULTS_FILE"
|
|
echo "=== CRON MANAGEMENT CONCLUSION ===" >> "$RESULTS_FILE"
|
|
if [ -n "$CRON_USER" ]; then
|
|
echo "RECOMMENDED: Use standard crontab -u $CRON_USER for cron jobs" >> "$RESULTS_FILE"
|
|
fi
|
|
if [ $HAS_PLESK_CRON -eq 1 ]; then
|
|
echo "ALTERNATIVE: Plesk bin cron available but may be for web UI management only" >> "$RESULTS_FILE"
|
|
fi
|
|
|
|
else
|
|
test_fail "crontab command not available"
|
|
fi
|
|
|
|
################################################################################
|
|
# TEST 10: PHP Configuration
|
|
################################################################################
|
|
|
|
section_header "TEST 10: PHP Configuration"
|
|
|
|
# Check PHP versions
|
|
test_info "Checking available PHP versions:"
|
|
|
|
# Plesk-specific PHP locations
|
|
if [ -d "/opt/plesk/php" ]; then
|
|
test_pass "Plesk PHP directory exists: /opt/plesk/php"
|
|
test_info "Plesk PHP versions:"
|
|
ls -d /opt/plesk/php/*/ 2>/dev/null >> "$RESULTS_FILE"
|
|
fi
|
|
|
|
# System PHP versions
|
|
PHP_BINS=$(find /usr/bin /opt -name "php" -o -name "php[0-9]*" 2>/dev/null | grep -E "php[0-9]|php$" | head -10)
|
|
if [ -n "$PHP_BINS" ]; then
|
|
test_info "Available PHP binaries:"
|
|
echo "$PHP_BINS" >> "$RESULTS_FILE"
|
|
fi
|
|
|
|
# Check PHP-FPM pools
|
|
if [ -d "/etc/php-fpm.d" ]; then
|
|
test_pass "PHP-FPM pool directory exists: /etc/php-fpm.d"
|
|
POOL_COUNT=$(ls /etc/php-fpm.d/*.conf 2>/dev/null | wc -l)
|
|
test_info "Found $POOL_COUNT PHP-FPM pool config(s)"
|
|
elif [ -d "/etc/php/*/fpm/pool.d" ]; then
|
|
test_pass "PHP-FPM pool directory exists (Debian/Ubuntu pattern)"
|
|
fi
|
|
|
|
# Check how domain selects PHP version
|
|
if [ -n "$TEST_DOMAIN" ]; then
|
|
test_info "Checking PHP handler for $TEST_DOMAIN:"
|
|
|
|
# Try plesk bin command
|
|
PHP_HANDLER=$(plesk bin site -i "$TEST_DOMAIN" 2>/dev/null | grep -i "php")
|
|
if [ -n "$PHP_HANDLER" ]; then
|
|
test_pass "Retrieved PHP handler info via plesk bin site"
|
|
echo "$PHP_HANDLER" >> "$RESULTS_FILE"
|
|
else
|
|
test_warn "Could not retrieve PHP handler info"
|
|
fi
|
|
fi
|
|
|
|
################################################################################
|
|
# TEST 11: WordPress Detection
|
|
################################################################################
|
|
|
|
section_header "TEST 11: WordPress Detection"
|
|
|
|
test_info "Searching for WordPress installations..."
|
|
|
|
WP_SITES=$(find /var/www/vhosts -maxdepth 3 -name "wp-config.php" -type f 2>/dev/null | head -10)
|
|
|
|
if [ -n "$WP_SITES" ]; then
|
|
WP_COUNT=$(echo "$WP_SITES" | wc -l)
|
|
test_pass "Found $WP_COUNT WordPress installation(s)"
|
|
|
|
# Test path pattern
|
|
FIRST_WP=$(echo "$WP_SITES" | head -1)
|
|
test_info "Sample WordPress path: $FIRST_WP"
|
|
|
|
# Verify it matches expected pattern: /var/www/vhosts/DOMAIN/httpdocs/wp-config.php
|
|
if echo "$FIRST_WP" | grep -qE "^/var/www/vhosts/[^/]+/httpdocs/wp-config.php$"; then
|
|
test_pass "WordPress path matches expected pattern: /var/www/vhosts/DOMAIN/httpdocs/wp-config.php"
|
|
test_pass "VERIFIED: WordPress detection pattern works"
|
|
else
|
|
test_warn "WordPress path doesn't match expected pattern (may be in subdirectory)"
|
|
test_info "Actual pattern found: $FIRST_WP"
|
|
fi
|
|
|
|
# Extract domain from path
|
|
WP_DOMAIN=$(echo "$FIRST_WP" | grep -oE '/vhosts/[^/]+' | sed 's|/vhosts/||')
|
|
test_info "Extracted domain from path: $WP_DOMAIN"
|
|
|
|
# Try to lookup owner
|
|
WP_OWNER=$(plesk bin subscription --info "$WP_DOMAIN" 2>/dev/null | grep -i "^Owner:" | awk '{print $2}')
|
|
if [ -n "$WP_OWNER" ]; then
|
|
test_info "WordPress site owner: $WP_OWNER"
|
|
fi
|
|
|
|
else
|
|
test_warn "No WordPress installations found (this is OK if none installed)"
|
|
fi
|
|
|
|
################################################################################
|
|
# TEST 12: Apache/Web Server Configuration
|
|
################################################################################
|
|
|
|
section_header "TEST 12: Apache/Web Server Configuration"
|
|
|
|
# Check Apache/httpd config
|
|
if [ -d "/etc/httpd/conf.d" ]; then
|
|
test_pass "Apache conf.d directory exists: /etc/httpd/conf.d"
|
|
elif [ -d "/etc/apache2/sites-enabled" ]; then
|
|
test_pass "Apache sites-enabled directory exists: /etc/apache2/sites-enabled"
|
|
fi
|
|
|
|
# Check for Plesk Apache configs
|
|
if [ -d "/usr/local/psa/admin/conf" ]; then
|
|
test_pass "Plesk admin conf directory exists"
|
|
fi
|
|
|
|
# Check if Apache or nginx
|
|
if ps aux | grep -v grep | grep -q "nginx"; then
|
|
test_info "System is using nginx"
|
|
if ps aux | grep -v grep | grep -q "httpd\|apache"; then
|
|
test_info "System is using nginx + Apache (Plesk typical setup)"
|
|
fi
|
|
elif ps aux | grep -v grep | grep -q "httpd\|apache"; then
|
|
test_info "System is using Apache only"
|
|
fi
|
|
|
|
################################################################################
|
|
# TEST 13: WordPress File Permissions & wp-config.php Access
|
|
################################################################################
|
|
|
|
section_header "TEST 13: WordPress File Permissions & wp-config.php Access"
|
|
|
|
if [ -n "$FIRST_WP" ]; then
|
|
test_info "Testing WordPress file access: $FIRST_WP"
|
|
|
|
# Check if we can read wp-config.php
|
|
if [ -r "$FIRST_WP" ]; then
|
|
test_pass "✓ CAN READ wp-config.php as root"
|
|
|
|
# Check file ownership
|
|
WP_OWNER=$(stat -c '%U' "$FIRST_WP" 2>/dev/null || stat -f '%Su' "$FIRST_WP" 2>/dev/null)
|
|
WP_PERMS=$(stat -c '%a' "$FIRST_WP" 2>/dev/null || stat -f '%Lp' "$FIRST_WP" 2>/dev/null)
|
|
|
|
test_info "wp-config.php owner: $WP_OWNER"
|
|
test_info "wp-config.php permissions: $WP_PERMS"
|
|
|
|
# Try to extract database info
|
|
DB_NAME=$(grep "DB_NAME" "$FIRST_WP" 2>/dev/null | head -1 | cut -d"'" -f4)
|
|
DB_USER=$(grep "DB_USER" "$FIRST_WP" 2>/dev/null | head -1 | cut -d"'" -f4)
|
|
|
|
if [ -n "$DB_NAME" ]; then
|
|
test_pass "✓ Can extract database name: $DB_NAME"
|
|
test_info "Database user: $DB_USER"
|
|
|
|
# Check if DB name has prefix
|
|
if echo "$DB_NAME" | grep -q "_"; then
|
|
test_info "Database has underscore (may have prefix)"
|
|
else
|
|
test_info "Database has NO underscore (likely no prefix)"
|
|
fi
|
|
else
|
|
test_warn "Could not extract database info from wp-config.php"
|
|
fi
|
|
|
|
else
|
|
test_fail "✗ CANNOT READ wp-config.php (permission denied)"
|
|
fi
|
|
|
|
# Check WordPress installation directory
|
|
WP_DIR=$(dirname "$FIRST_WP")
|
|
test_info "WordPress directory: $WP_DIR"
|
|
|
|
# List directory permissions
|
|
WP_DIR_OWNER=$(stat -c '%U:%G' "$WP_DIR" 2>/dev/null || stat -f '%Su:%Sg' "$WP_DIR" 2>/dev/null)
|
|
WP_DIR_PERMS=$(stat -c '%a' "$WP_DIR" 2>/dev/null || stat -f '%Lp' "$WP_DIR" 2>/dev/null)
|
|
|
|
test_info "WordPress dir owner: $WP_DIR_OWNER"
|
|
test_info "WordPress dir permissions: $WP_DIR_PERMS"
|
|
fi
|
|
|
|
################################################################################
|
|
# TEST 14: Comprehensive System Documentation
|
|
################################################################################
|
|
|
|
section_header "TEST 14: Comprehensive System Documentation"
|
|
|
|
test_info "Gathering complete system information for future reference..."
|
|
|
|
# Document all Plesk binaries
|
|
test_info "Cataloging Plesk bin commands..."
|
|
if [ -d "/usr/local/psa/bin" ]; then
|
|
echo "" >> "$RESULTS_FILE"
|
|
echo "=== ALL PLESK BIN COMMANDS ===" >> "$RESULTS_FILE"
|
|
ls -1 /usr/local/psa/bin >> "$RESULTS_FILE"
|
|
fi
|
|
|
|
# Document Plesk version info
|
|
test_info "Documenting Plesk version details..."
|
|
if command -v plesk &> /dev/null; then
|
|
echo "" >> "$RESULTS_FILE"
|
|
echo "=== PLESK VERSION DETAILS ===" >> "$RESULTS_FILE"
|
|
plesk version 2>/dev/null >> "$RESULTS_FILE"
|
|
fi
|
|
|
|
# Document all domains on system
|
|
test_info "Cataloging all domains on system..."
|
|
ALL_DOMAINS=$(find /var/www/vhosts -maxdepth 1 -type d ! -name "vhosts" ! -name "system" ! -name "default" ! -name "chroot" 2>/dev/null | xargs -n1 basename | sort)
|
|
if [ -n "$ALL_DOMAINS" ]; then
|
|
DOMAIN_COUNT=$(echo "$ALL_DOMAINS" | wc -l)
|
|
echo "" >> "$RESULTS_FILE"
|
|
echo "=== ALL DOMAINS ON SYSTEM (Total: $DOMAIN_COUNT) ===" >> "$RESULTS_FILE"
|
|
echo "$ALL_DOMAINS" >> "$RESULTS_FILE"
|
|
fi
|
|
|
|
# Document PHP versions available
|
|
test_info "Documenting all PHP versions..."
|
|
echo "" >> "$RESULTS_FILE"
|
|
echo "=== PHP VERSIONS AVAILABLE ===" >> "$RESULTS_FILE"
|
|
if [ -d "/opt/plesk/php" ]; then
|
|
ls -1d /opt/plesk/php/*/ 2>/dev/null | xargs -n1 basename >> "$RESULTS_FILE"
|
|
fi
|
|
which php 2>/dev/null >> "$RESULTS_FILE"
|
|
php -v 2>/dev/null | head -1 >> "$RESULTS_FILE"
|
|
|
|
# Document Apache/nginx configuration
|
|
test_info "Documenting web server setup..."
|
|
echo "" >> "$RESULTS_FILE"
|
|
echo "=== WEB SERVER CONFIGURATION ===" >> "$RESULTS_FILE"
|
|
if ps aux | grep -v grep | grep -q "nginx"; then
|
|
echo "nginx: RUNNING" >> "$RESULTS_FILE"
|
|
nginx -v 2>&1 >> "$RESULTS_FILE"
|
|
fi
|
|
if ps aux | grep -v grep | grep -q "httpd\|apache"; then
|
|
echo "Apache: RUNNING" >> "$RESULTS_FILE"
|
|
httpd -v 2>&1 >> "$RESULTS_FILE" || apache2 -v 2>&1 >> "$RESULTS_FILE"
|
|
fi
|
|
|
|
# Document database server
|
|
test_info "Documenting database server..."
|
|
echo "" >> "$RESULTS_FILE"
|
|
echo "=== DATABASE SERVER ===" >> "$RESULTS_FILE"
|
|
if command -v mysql &> /dev/null; then
|
|
mysql -V >> "$RESULTS_FILE" 2>&1
|
|
fi
|
|
|
|
# Create a quick reference for developers
|
|
echo "" >> "$RESULTS_FILE"
|
|
echo "=======================================================================" >> "$RESULTS_FILE"
|
|
echo "QUICK REFERENCE FOR DEVELOPERS" >> "$RESULTS_FILE"
|
|
echo "=======================================================================" >> "$RESULTS_FILE"
|
|
echo "" >> "$RESULTS_FILE"
|
|
echo "Document roots: /var/www/vhosts/DOMAIN/httpdocs/" >> "$RESULTS_FILE"
|
|
echo "Access logs: /var/www/vhosts/system/DOMAIN/logs/access_log" >> "$RESULTS_FILE"
|
|
echo "Error logs: /var/www/vhosts/system/DOMAIN/logs/error_log" >> "$RESULTS_FILE"
|
|
echo "WordPress: /var/www/vhosts/DOMAIN/httpdocs/wp-config.php" >> "$RESULTS_FILE"
|
|
echo "" >> "$RESULTS_FILE"
|
|
|
|
if [ -n "$CRON_USER" ]; then
|
|
echo "Cron user: $CRON_USER" >> "$RESULTS_FILE"
|
|
echo "Cron command: crontab -u $CRON_USER" >> "$RESULTS_FILE"
|
|
fi
|
|
|
|
if [ -n "$DB_NAME" ]; then
|
|
echo "" >> "$RESULTS_FILE"
|
|
echo "Sample database: $DB_NAME" >> "$RESULTS_FILE"
|
|
if echo "$DB_NAME" | grep -q "_"; then
|
|
echo "Database prefix: APPEARS TO HAVE PREFIX" >> "$RESULTS_FILE"
|
|
else
|
|
echo "Database prefix: APPEARS TO BE NO PREFIX" >> "$RESULTS_FILE"
|
|
fi
|
|
fi
|
|
|
|
################################################################################
|
|
# SUMMARY
|
|
################################################################################
|
|
|
|
section_header "VALIDATION SUMMARY"
|
|
|
|
TOTAL=$((PASS + FAIL + WARN))
|
|
|
|
echo ""
|
|
echo "======================================================================="
|
|
echo "RESULTS SUMMARY"
|
|
echo "======================================================================="
|
|
echo -e "${GREEN}PASS: $PASS${NC}"
|
|
echo -e "${RED}FAIL: $FAIL${NC}"
|
|
echo -e "${YELLOW}WARN: $WARN${NC}"
|
|
echo "TOTAL TESTS: $TOTAL"
|
|
echo ""
|
|
|
|
cat >> "$RESULTS_FILE" <<EOF
|
|
|
|
======================================================================
|
|
RESULTS SUMMARY
|
|
======================================================================
|
|
PASS: $PASS
|
|
FAIL: $FAIL
|
|
WARN: $WARN
|
|
TOTAL TESTS: $TOTAL
|
|
|
|
Completed: $(date)
|
|
EOF
|
|
|
|
if [ $FAIL -eq 0 ]; then
|
|
echo -e "${GREEN}✓ ALL CRITICAL TESTS PASSED${NC}"
|
|
echo "✓ ALL CRITICAL TESTS PASSED" >> "$RESULTS_FILE"
|
|
echo ""
|
|
echo "Plesk validation successful!"
|
|
echo ""
|
|
echo "CRITICAL ANSWERS DISCOVERED:"
|
|
if [ -n "$CRON_USER" ]; then
|
|
echo " • Cron user: $CRON_USER"
|
|
fi
|
|
if [ -n "$DB_NAME" ]; then
|
|
echo " • Database pattern: $(echo "$DB_NAME" | grep -q "_" && echo "HAS PREFIX" || echo "NO PREFIX")"
|
|
fi
|
|
if [ -n "$FILE_OWNER" ]; then
|
|
echo " • File ownership: $FILE_OWNER"
|
|
fi
|
|
else
|
|
echo -e "${RED}✗ SOME TESTS FAILED - REVIEW RESULTS${NC}"
|
|
echo "✗ SOME TESTS FAILED - REVIEW RESULTS" >> "$RESULTS_FILE"
|
|
fi
|
|
|
|
echo ""
|
|
echo "Full results saved to: $RESULTS_FILE"
|
|
echo ""
|
|
echo "======================================================================="
|
|
echo "NEXT STEPS:"
|
|
echo "======================================================================="
|
|
echo "1. Review $RESULTS_FILE for complete details"
|
|
echo "2. Report findings to development team"
|
|
echo "3. Test actual toolkit modules if validation passed"
|
|
echo "======================================================================="
|
|
|
|
exit 0
|