Files
Linux-Server-Management-Too…/lib/plesk-helpers.sh
T
cschantz c1f2f6868d Add comprehensive Plesk control panel support
Core Infrastructure Added:
- lib/plesk-helpers.sh: 30+ Plesk-specific helper functions
  - Domain discovery (list, docroot, logdir, access/error logs)
  - User/subscription management
  - Database discovery
  - PHP version detection (/opt/plesk/php/)
  - PHP-FPM pool discovery
  - Configuration file locations
  - Mail functions
  - Service management
  - Version detection with log structure handling

- lib/domain-discovery.sh: Unified control panel abstraction
  - Consistent API across cPanel, Plesk, InterWorx, standalone
  - list_all_domains() - works on any panel
  - get_domain_docroot() - panel-agnostic document root
  - get_domain_logdir() - panel-agnostic log discovery
  - get_domain_access_log() - access log paths
  - get_domain_error_log() - error log paths
  - get_all_log_files() - all logs across all domains
  - get_domain_owner() - domain owner/user
  - list_all_users() - user enumeration
  - get_domain_fpm_socket() - PHP-FPM pool sockets
  - get_domain_databases() - database discovery
  - domain_exists() - existence checks

Documentation:
- PLESK_REFERENCE.md: Complete Plesk architecture reference
  - Directory structure mapping
  - Log file locations (current & future versions)
  - PHP-FPM pool locations
  - Configuration file paths
  - Plesk CLI command reference
  - Key differences from cPanel
  - Subdomain handling differences

- PLESK_SUPPORT_SUMMARY.md: Implementation summary
  - All functions documented
  - Usage examples
  - Migration guide for existing modules
  - Version compatibility notes
  - Testing checklist

System Detection Enhanced:
- lib/system-detect.sh:
  - Improved Plesk detection with version-aware log paths
  - Auto-sources plesk-helpers.sh when Plesk detected
  - Added /opt/plesk/php/ scanning for PHP versions
  - Sets SYS_USER_HOME_BASE=/var/www/vhosts for Plesk

Email Menu Added:
- launcher.sh: New Email Troubleshooting menu category
  - 9 email diagnostic/maintenance tools (placeholders)
  - Deliverability test, queue inspector, SMTP test
  - SPF/DKIM/DMARC check, blacklist check
  - Mail log analyzer, queue flush
  - Mailbox cleanup, size reports

Plesk Architecture Support:
- /var/www/vhosts/ base directory structure
- system/DOMAIN/logs/ for Plesk <18.0.50
- DOMAIN/logs/ for Plesk 18.0.50+
- Automatic version detection
- Subdomain separate directory handling
- /opt/plesk/php/X.Y/ PHP version detection
- /var/www/vhosts/system/DOMAIN/php-fpm.sock pools
- /var/www/vhosts/system/DOMAIN/conf/ configs

Fallback Mechanisms:
- All functions work with or without Plesk CLI
- Directory scanning fallbacks
- MySQL direct query fallbacks
- Path inference from standard locations

Status: Core infrastructure complete, ready for module integration
Next: Test on actual Plesk server, update existing modules

Ref: system_map.tsv analysis from Plesk production system
2025-12-23 20:20:09 -05:00

473 lines
13 KiB
Bash

#!/bin/bash
#############################################################################
# Plesk Helper Functions
# Provides Plesk-specific utilities for domain, user, and resource discovery
#############################################################################
# Source common functions if not already loaded
if [ -z "$TOOLKIT_BASE_DIR" ]; then
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/common-functions.sh"
fi
#############################################################################
# PLESK CLI HELPERS
#############################################################################
# Check if Plesk CLI is available
plesk_cli_available() {
[ -x "/usr/local/psa/bin/plesk" ]
}
# Execute Plesk CLI command with error handling
plesk_exec() {
if ! plesk_cli_available; then
print_error "Plesk CLI not available"
return 1
fi
/usr/local/psa/bin/plesk "$@" 2>/dev/null
}
#############################################################################
# DOMAIN DISCOVERY
#############################################################################
# Get list of all domains
# Returns: One domain per line
plesk_list_domains() {
if plesk_cli_available; then
plesk_exec bin domain --list 2>/dev/null
else
# Fallback: scan vhosts directory
ls -1 /var/www/vhosts/ 2>/dev/null | \
grep -v "^system$\|^chroot$\|^\.skel$\|^default$\|^fs$" | \
grep -v "^\." || true
fi
}
# Get domain info
# Usage: plesk_domain_info DOMAIN
plesk_domain_info() {
local domain="$1"
[ -z "$domain" ] && return 1
plesk_exec bin domain --info "$domain" 2>/dev/null
}
# Get domain document root
# Usage: plesk_get_docroot DOMAIN
# Returns: /var/www/vhosts/DOMAIN/httpdocs
plesk_get_docroot() {
local domain="$1"
[ -z "$domain" ] && return 1
if plesk_cli_available; then
plesk_domain_info "$domain" | grep -oP "www root:\s+\K.*" 2>/dev/null | head -1
else
# Fallback: standard path
local docroot="/var/www/vhosts/$domain/httpdocs"
[ -d "$docroot" ] && echo "$docroot"
fi
}
# Get domain log directory
# Usage: plesk_get_logdir DOMAIN
# Returns: /var/www/vhosts/system/DOMAIN/logs (current) or /var/www/vhosts/DOMAIN/logs (future)
plesk_get_logdir() {
local domain="$1"
[ -z "$domain" ] && return 1
# Check new location first (Plesk 18.0.50+)
if [ -d "/var/www/vhosts/$domain/logs" ]; then
echo "/var/www/vhosts/$domain/logs"
return 0
fi
# Check old location (Plesk 17.x - 18.0.49)
if [ -d "/var/www/vhosts/system/$domain/logs" ]; then
echo "/var/www/vhosts/system/$domain/logs"
return 0
fi
return 1
}
# Get all domain log directories
# Returns: One log directory path per line for all domains
plesk_get_all_logdirs() {
local logdirs=()
# Try new location (Plesk 18.0.50+)
while IFS= read -r dir; do
[ -d "$dir" ] && logdirs+=("$dir")
done < <(find /var/www/vhosts/*/logs -maxdepth 0 -type d 2>/dev/null | grep -v "/system/")
# Try old location (Plesk 17.x - 18.0.49)
while IFS= read -r dir; do
[ -d "$dir" ] && logdirs+=("$dir")
done < <(find /var/www/vhosts/system/*/logs -maxdepth 0 -type d 2>/dev/null)
# Remove duplicates and print
printf '%s\n' "${logdirs[@]}" | sort -u
}
# Get domain access log path
# Usage: plesk_get_access_log DOMAIN [ssl]
# Returns: Full path to access log
plesk_get_access_log() {
local domain="$1"
local ssl="${2:-}"
local logdir
logdir=$(plesk_get_logdir "$domain")
[ -z "$logdir" ] && return 1
if [ "$ssl" = "ssl" ]; then
echo "$logdir/access_ssl_log"
else
echo "$logdir/access_log"
fi
}
# Get domain error log path
# Usage: plesk_get_error_log DOMAIN
plesk_get_error_log() {
local domain="$1"
local logdir
logdir=$(plesk_get_logdir "$domain")
[ -z "$logdir" ] && return 1
echo "$logdir/error_log"
}
#############################################################################
# USER/SUBSCRIPTION MANAGEMENT
#############################################################################
# Get list of all subscriptions
plesk_list_subscriptions() {
if plesk_cli_available; then
plesk_exec bin subscription --list 2>/dev/null
else
plesk_list_domains
fi
}
# Get subscription owner for domain
# Usage: plesk_get_owner DOMAIN
plesk_get_owner() {
local domain="$1"
[ -z "$domain" ] && return 1
if plesk_cli_available; then
plesk_exec bin subscription --info "$domain" 2>/dev/null | \
grep -oP "Owner's login:\s+\K.*" | head -1
else
# Fallback: check directory ownership
stat -c "%U" "/var/www/vhosts/$domain" 2>/dev/null
fi
}
#############################################################################
# DATABASE DISCOVERY
#############################################################################
# List all databases
plesk_list_databases() {
if plesk_cli_available; then
plesk_exec bin database --list 2>/dev/null
else
# Fallback: query MySQL directly
mysql -e "SHOW DATABASES;" 2>/dev/null | grep -v "Database\|information_schema\|performance_schema\|mysql\|sys"
fi
}
# List databases for specific domain
# Usage: plesk_list_domain_databases DOMAIN
plesk_list_domain_databases() {
local domain="$1"
[ -z "$domain" ] && return 1
if plesk_cli_available; then
plesk_exec bin database --list -domain "$domain" 2>/dev/null
else
# Fallback: guess based on naming convention (domain_dbname)
local db_prefix=$(echo "$domain" | tr '.' '_' | tr '-' '_')
plesk_list_databases | grep "^${db_prefix}_"
fi
}
#############################################################################
# PHP VERSION DETECTION
#############################################################################
# List all available PHP handlers
plesk_list_php_handlers() {
if plesk_cli_available; then
plesk_exec bin php_handler --list 2>/dev/null
else
# Fallback: scan for PHP binaries
find /opt/plesk/php/*/bin/php -type f -executable 2>/dev/null
fi
}
# Get PHP version for domain
# Usage: plesk_get_domain_php DOMAIN
plesk_get_domain_php() {
local domain="$1"
[ -z "$domain" ] && return 1
if plesk_cli_available; then
plesk_exec bin site --info "$domain" 2>/dev/null | \
grep -oP "PHP version:\s+\K.*" | head -1
else
# Fallback: check php-fpm socket config
local php_ini="/var/www/vhosts/system/$domain/etc/php.ini"
if [ -f "$php_ini" ]; then
grep "^; configuration file" "$php_ini" | grep -oP '\d+\.\d+' | head -1
fi
fi
}
# Detect all Plesk-managed PHP versions
plesk_detect_php_versions() {
local versions=()
# Scan /opt/plesk/php/
for php_bin in /opt/plesk/php/*/bin/php; do
if [ -x "$php_bin" ]; then
local version=$("$php_bin" -v 2>/dev/null | grep -oP '^PHP \K[\d.]+' | head -1)
[ -n "$version" ] && versions+=("$version")
fi
done
# Remove duplicates
printf '%s\n' "${versions[@]}" | sort -u -V
}
#############################################################################
# PHP-FPM POOL DISCOVERY
#############################################################################
# Find all PHP-FPM pool sockets
plesk_list_fpm_sockets() {
find /var/www/vhosts/system/*/php-fpm.sock -type s 2>/dev/null
}
# Get PHP-FPM socket for domain
# Usage: plesk_get_fpm_socket DOMAIN
plesk_get_fpm_socket() {
local domain="$1"
[ -z "$domain" ] && return 1
local socket="/var/www/vhosts/system/$domain/php-fpm.sock"
[ -S "$socket" ] && echo "$socket"
}
#############################################################################
# CONFIGURATION FILE DISCOVERY
#############################################################################
# Get domain config directory
# Usage: plesk_get_confdir DOMAIN
plesk_get_confdir() {
local domain="$1"
[ -z "$domain" ] && return 1
local confdir="/var/www/vhosts/system/$domain/conf"
[ -d "$confdir" ] && echo "$confdir"
}
# Get Apache vhost config
# Usage: plesk_get_httpd_conf DOMAIN
plesk_get_httpd_conf() {
local domain="$1"
local confdir
confdir=$(plesk_get_confdir "$domain")
[ -z "$confdir" ] && return 1
echo "$confdir/httpd.conf"
}
# Get Nginx config
# Usage: plesk_get_nginx_conf DOMAIN
plesk_get_nginx_conf() {
local domain="$1"
local confdir
confdir=$(plesk_get_confdir "$domain")
[ -z "$confdir" ] && return 1
echo "$confdir/nginx.conf"
}
# Get PHP config (php.ini)
# Usage: plesk_get_php_ini DOMAIN
plesk_get_php_ini() {
local domain="$1"
[ -z "$domain" ] && return 1
local php_ini="/var/www/vhosts/system/$domain/etc/php.ini"
[ -f "$php_ini" ] && echo "$php_ini"
}
#############################################################################
# MAIL FUNCTIONS
#############################################################################
# Get mailbox directory for user@domain
# Usage: plesk_get_mailbox_dir DOMAIN USERNAME
plesk_get_mailbox_dir() {
local domain="$1"
local username="$2"
[ -z "$domain" ] || [ -z "$username" ] && return 1
local maildir="/var/qmail/mailnames/$domain/$username/Maildir"
[ -d "$maildir" ] && echo "$maildir"
}
# List all mailboxes for domain
# Usage: plesk_list_mailboxes DOMAIN
plesk_list_mailboxes() {
local domain="$1"
[ -z "$domain" ] && return 1
if plesk_cli_available; then
plesk_exec bin mail --list "$domain" 2>/dev/null
else
# Fallback: scan mailnames directory
[ -d "/var/qmail/mailnames/$domain" ] && \
ls -1 /var/qmail/mailnames/$domain/ 2>/dev/null
fi
}
#############################################################################
# SERVICE MANAGEMENT
#############################################################################
# Restart Apache
plesk_restart_apache() {
if plesk_cli_available; then
plesk_exec bin service_node --restart httpd
else
systemctl restart httpd 2>/dev/null || service httpd restart 2>/dev/null
fi
}
# Restart Nginx
plesk_restart_nginx() {
if plesk_cli_available; then
plesk_exec bin service_node --restart nginx
else
systemctl restart nginx 2>/dev/null || service nginx restart 2>/dev/null
fi
}
# Restart PHP-FPM for all versions
plesk_restart_phpfpm() {
if plesk_cli_available; then
# Restart all Plesk PHP-FPM services
for service in /etc/systemd/system/plesk-php*-fpm.service; do
[ -f "$service" ] && systemctl restart "$(basename "$service")" 2>/dev/null
done
else
systemctl restart php-fpm 2>/dev/null || service php-fpm restart 2>/dev/null
fi
}
#############################################################################
# UTILITY FUNCTIONS
#############################################################################
# Check if domain exists in Plesk
# Usage: plesk_domain_exists DOMAIN
plesk_domain_exists() {
local domain="$1"
[ -z "$domain" ] && return 1
if plesk_cli_available; then
plesk_domain_info "$domain" > /dev/null 2>&1
return $?
else
[ -d "/var/www/vhosts/$domain" ] || [ -d "/var/www/vhosts/system/$domain" ]
fi
}
# Get Plesk version
plesk_get_version() {
if [ -f "/usr/local/psa/version" ]; then
head -1 /usr/local/psa/version
else
echo "unknown"
fi
}
# Check if Plesk version is 18.0.50 or higher (new log location)
plesk_is_new_log_structure() {
local version
version=$(plesk_get_version)
# Parse version (format: 18.0.50)
local major minor patch
major=$(echo "$version" | cut -d'.' -f1)
minor=$(echo "$version" | cut -d'.' -f2)
patch=$(echo "$version" | cut -d'.' -f3)
# Check if >= 18.0.50
if [ "$major" -gt 18 ]; then
return 0
elif [ "$major" -eq 18 ] && [ "$minor" -gt 0 ]; then
return 0
elif [ "$major" -eq 18 ] && [ "$minor" -eq 0 ] && [ "${patch:-0}" -ge 50 ]; then
return 0
fi
return 1
}
# Get all domain names and document roots as TSV
# Format: DOMAIN\t/path/to/httpdocs
plesk_list_domains_with_docroots() {
local domain docroot
while IFS= read -r domain; do
docroot=$(plesk_get_docroot "$domain")
[ -n "$docroot" ] && echo -e "$domain\t$docroot"
done < <(plesk_list_domains)
}
# Export all functions
export -f plesk_cli_available
export -f plesk_exec
export -f plesk_list_domains
export -f plesk_domain_info
export -f plesk_get_docroot
export -f plesk_get_logdir
export -f plesk_get_all_logdirs
export -f plesk_get_access_log
export -f plesk_get_error_log
export -f plesk_list_subscriptions
export -f plesk_get_owner
export -f plesk_list_databases
export -f plesk_list_domain_databases
export -f plesk_list_php_handlers
export -f plesk_get_domain_php
export -f plesk_detect_php_versions
export -f plesk_list_fpm_sockets
export -f plesk_get_fpm_socket
export -f plesk_get_confdir
export -f plesk_get_httpd_conf
export -f plesk_get_nginx_conf
export -f plesk_get_php_ini
export -f plesk_get_mailbox_dir
export -f plesk_list_mailboxes
export -f plesk_restart_apache
export -f plesk_restart_nginx
export -f plesk_restart_phpfpm
export -f plesk_domain_exists
export -f plesk_get_version
export -f plesk_is_new_log_structure
export -f plesk_list_domains_with_docroots