Files
Linux-Server-Management-Too…/lib/php-config-manager.sh
T
cschantz f20c0edf2b Phase 4: Implement backup/restore system with PHP-FPM restart capability
NEW LIBRARY: lib/php-config-manager.sh (14 functions, 442 lines)

BACKUP FUNCTIONS:
- initialize_backup_system() - Creates /root/server-toolkit/backups/php/
- backup_php_config() - Backs up single config file with metadata
- backup_fpm_pool() - Backs up PHP-FPM pool configuration
- backup_user_php_configs() - Backs up ALL PHP configs for a user
- list_backups() - Lists all backups with metadata (date, user, domain, file count)

RESTORE FUNCTIONS:
- restore_php_config() - Restores single config file
- restore_from_backup() - Restores entire backup set
- delete_backup() - Removes old backups

CONFIGURATION MODIFICATION:
- modify_fpm_pool_setting() - Changes single FPM pool setting
- modify_php_ini_setting() - Changes single php.ini setting
- apply_fpm_pool_settings() - Applies multiple settings at once

PHP-FPM MANAGEMENT:
- restart_php_fpm() - Restarts PHP-FPM service (systemd/sysvinit)
- reload_php_fpm() - Graceful reload (no downtime)
- verify_php_fpm_running() - Checks if service is active

MENU OPTIONS B & R IMPLEMENTED:

Option B: Backup Current Configurations
  - Select domain to backup
  - Backs up all php.ini files (priority 1-4)
  - Backs up PHP-FPM pool config
  - Creates metadata.txt with timestamp, user, domain
  - Preserves directory structure
  - Shows list of backed up files
  - Backup location: /root/server-toolkit/backups/php/YYYYMMDD_HHMMSS/

Option R: Restore from Backup
  - Lists all available backups with details
  - Shows: backup name, date, username, domain, file count
  - Numbered selection menu
  - Confirmation prompt: "This will overwrite current configurations!"
  - Requires typing "yes" to proceed
  - Restores all files with metadata preservation
  - Shows success/failure for each file
  - Reminder to restart PHP-FPM

BACKUP STRUCTURE:
/root/server-toolkit/backups/php/
├── 20250102_143045/
│   ├── metadata.txt (backup info)
│   ├── opt/cpanel/ea-php82/root/etc/php-fpm.d/username.conf
│   ├── home/username/.php/8.2/php.ini
│   └── home/username/public_html/.user.ini
└── 20250102_150830/
    └── ...

SAFETY FEATURES:
- Metadata tracking (who, what, when)
- Confirmation required for restore
- Non-destructive backups (never overwrites backups)
- Timestamp-based naming (no conflicts)
- Preserves file permissions and ownership

FUTURE USE:
These functions will be used by Phase 5 (apply/action menu) to:
1. Auto-backup before applying changes
2. Rollback if changes cause issues
3. Compare current vs backed up configs
2025-12-02 20:46:28 -05:00

509 lines
14 KiB
Bash

#!/bin/bash
# PHP Configuration Manager
# Handles backup, restore, and modification of PHP configurations
# Part of Server Toolkit - Configuration Management
# Backup directory
BACKUP_DIR="/root/server-toolkit/backups/php"
BACKUP_TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# ============================================================================
# BACKUP FUNCTIONS
# ============================================================================
# Create backup directory structure
initialize_backup_system() {
mkdir -p "$BACKUP_DIR"
if [ ! -d "$BACKUP_DIR" ]; then
echo "ERROR: Failed to create backup directory: $BACKUP_DIR"
return 1
fi
return 0
}
# Backup a single PHP configuration file
# Usage: backup_php_config <config_file> [backup_name]
backup_php_config() {
local config_file="$1"
local backup_name="${2:-$BACKUP_TIMESTAMP}"
if [ ! -f "$config_file" ]; then
echo "ERROR: Config file not found: $config_file"
return 1
fi
# Create backup subdirectory
local backup_subdir="$BACKUP_DIR/$backup_name"
mkdir -p "$backup_subdir"
# Preserve directory structure
local relative_path="${config_file#/}"
local backup_path="$backup_subdir/$relative_path"
local backup_dir_path=$(dirname "$backup_path")
mkdir -p "$backup_dir_path"
# Copy with metadata preservation
cp -p "$config_file" "$backup_path"
if [ $? -eq 0 ]; then
echo "$backup_path"
return 0
else
echo "ERROR: Failed to backup $config_file"
return 1
fi
}
# Backup PHP-FPM pool configuration
# Usage: backup_fpm_pool <username> [backup_name]
backup_fpm_pool() {
local username="$1"
local backup_name="${2:-$BACKUP_TIMESTAMP}"
# Source php-detector to find pool config
local pool_config
pool_config=$(find_fpm_pool_config "$username")
if [ -z "$pool_config" ] || [ ! -f "$pool_config" ]; then
echo "ERROR: FPM pool config not found for $username"
return 1
fi
backup_php_config "$pool_config" "$backup_name"
}
# Backup all PHP configs for a user
# Usage: backup_user_php_configs <username> <domain> [backup_name]
backup_user_php_configs() {
local username="$1"
local domain="$2"
local backup_name="${3:-$BACKUP_TIMESTAMP}"
initialize_backup_system || return 1
local backup_subdir="$BACKUP_DIR/$backup_name"
mkdir -p "$backup_subdir"
# Create backup metadata
cat > "$backup_subdir/metadata.txt" <<EOF
Backup Created: $(date)
Username: $username
Domain: $domain
Backup Name: $backup_name
EOF
local backed_up_files=()
# Find and backup all config files
local configs
configs=$(find_all_php_configs "$username" "$domain")
while IFS= read -r config; do
[ -z "$config" ] && continue
[ ! -f "$config" ] && continue
local backup_path
backup_path=$(backup_php_config "$config" "$backup_name")
if [ $? -eq 0 ]; then
backed_up_files+=("$config")
echo "Files backed up:" >> "$backup_subdir/metadata.txt"
echo " $config$backup_path" >> "$backup_subdir/metadata.txt"
fi
done <<< "$configs"
# Backup FPM pool config
local pool_config
pool_config=$(find_fpm_pool_config "$username")
if [ -n "$pool_config" ] && [ -f "$pool_config" ]; then
local backup_path
backup_path=$(backup_php_config "$pool_config" "$backup_name")
if [ $? -eq 0 ]; then
backed_up_files+=("$pool_config")
echo " $pool_config$backup_path" >> "$backup_subdir/metadata.txt"
fi
fi
# Return backup location
if [ ${#backed_up_files[@]} -gt 0 ]; then
echo "$backup_subdir"
return 0
else
echo "ERROR: No files backed up"
return 1
fi
}
# List all backups
# Usage: list_backups
list_backups() {
if [ ! -d "$BACKUP_DIR" ]; then
echo "No backups found"
return 1
fi
local backups
backups=$(find "$BACKUP_DIR" -mindepth 1 -maxdepth 1 -type d -name "2*" | sort -r)
if [ -z "$backups" ]; then
echo "No backups found"
return 1
fi
echo "BACKUP_NAME|DATE|USERNAME|DOMAIN|FILE_COUNT"
while IFS= read -r backup_dir; do
local backup_name=$(basename "$backup_dir")
local metadata_file="$backup_dir/metadata.txt"
if [ -f "$metadata_file" ]; then
local created=$(grep "^Backup Created:" "$metadata_file" | cut -d: -f2- | xargs)
local username=$(grep "^Username:" "$metadata_file" | cut -d: -f2 | xargs)
local domain=$(grep "^Domain:" "$metadata_file" | cut -d: -f2 | xargs)
local file_count=$(find "$backup_dir" -type f ! -name "metadata.txt" | wc -l)
echo "$backup_name|$created|$username|$domain|$file_count"
else
local file_count=$(find "$backup_dir" -type f | wc -l)
echo "$backup_name|Unknown|Unknown|Unknown|$file_count"
fi
done <<< "$backups"
}
# ============================================================================
# RESTORE FUNCTIONS
# ============================================================================
# Restore a single configuration file
# Usage: restore_php_config <backup_path> <original_path>
restore_php_config() {
local backup_path="$1"
local original_path="$2"
if [ ! -f "$backup_path" ]; then
echo "ERROR: Backup file not found: $backup_path"
return 1
fi
# Create directory if needed
local original_dir=$(dirname "$original_path")
mkdir -p "$original_dir"
# Restore with metadata preservation
cp -p "$backup_path" "$original_path"
if [ $? -eq 0 ]; then
echo "Restored: $original_path"
return 0
else
echo "ERROR: Failed to restore $original_path"
return 1
fi
}
# Restore from backup
# Usage: restore_from_backup <backup_name>
restore_from_backup() {
local backup_name="$1"
local backup_dir="$BACKUP_DIR/$backup_name"
if [ ! -d "$backup_dir" ]; then
echo "ERROR: Backup not found: $backup_name"
return 1
fi
# Read metadata
local metadata_file="$backup_dir/metadata.txt"
if [ ! -f "$metadata_file" ]; then
echo "ERROR: Backup metadata not found"
return 1
fi
echo "Restoring from backup: $backup_name"
cat "$metadata_file"
echo ""
# Find all backed up files (excluding metadata)
local restored_count=0
local failed_count=0
while IFS= read -r backup_file; do
# Extract original path from backup structure
local relative_path="${backup_file#$backup_dir/}"
local original_path="/$relative_path"
if restore_php_config "$backup_file" "$original_path"; then
restored_count=$((restored_count + 1))
else
failed_count=$((failed_count + 1))
fi
done < <(find "$backup_dir" -type f ! -name "metadata.txt")
echo ""
echo "Restore complete: $restored_count files restored, $failed_count failed"
if [ "$failed_count" -eq 0 ]; then
return 0
else
return 1
fi
}
# Delete a backup
# Usage: delete_backup <backup_name>
delete_backup() {
local backup_name="$1"
local backup_dir="$BACKUP_DIR/$backup_name"
if [ ! -d "$backup_dir" ]; then
echo "ERROR: Backup not found: $backup_name"
return 1
fi
rm -rf "$backup_dir"
if [ $? -eq 0 ]; then
echo "Backup deleted: $backup_name"
return 0
else
echo "ERROR: Failed to delete backup"
return 1
fi
}
# ============================================================================
# CONFIGURATION MODIFICATION FUNCTIONS
# ============================================================================
# Modify a PHP-FPM pool setting
# Usage: modify_fpm_pool_setting <pool_config_file> <setting> <value>
modify_fpm_pool_setting() {
local pool_config="$1"
local setting="$2"
local value="$3"
if [ ! -f "$pool_config" ]; then
echo "ERROR: Pool config not found: $pool_config"
return 1
fi
# Check if setting exists
if grep -q "^${setting}\s*=" "$pool_config"; then
# Replace existing value
sed -i "s|^${setting}\s*=.*|${setting} = ${value}|" "$pool_config"
elif grep -q "^;${setting}\s*=" "$pool_config"; then
# Uncomment and set value
sed -i "s|^;${setting}\s*=.*|${setting} = ${value}|" "$pool_config"
else
# Add new setting at end of file
echo "${setting} = ${value}" >> "$pool_config"
fi
if [ $? -eq 0 ]; then
echo "Modified: $setting = $value in $pool_config"
return 0
else
echo "ERROR: Failed to modify $setting"
return 1
fi
}
# Modify a php.ini setting
# Usage: modify_php_ini_setting <php_ini_file> <setting> <value>
modify_php_ini_setting() {
local php_ini="$1"
local setting="$2"
local value="$3"
if [ ! -f "$php_ini" ]; then
echo "ERROR: php.ini not found: $php_ini"
return 1
fi
# Check if setting exists
if grep -q "^${setting}\s*=" "$php_ini"; then
# Replace existing value
sed -i "s|^${setting}\s*=.*|${setting} = ${value}|" "$php_ini"
elif grep -q "^;${setting}\s*=" "$php_ini"; then
# Uncomment and set value
sed -i "s|^;${setting}\s*=.*|${setting} = ${value}|" "$php_ini"
else
# Add new setting at end of file
echo "${setting} = ${value}" >> "$php_ini"
fi
if [ $? -eq 0 ]; then
echo "Modified: $setting = $value in $php_ini"
return 0
else
echo "ERROR: Failed to modify $setting"
return 1
fi
}
# Apply multiple FPM pool settings
# Usage: apply_fpm_pool_settings <pool_config_file> <settings_array>
# settings_array format: "setting1=value1" "setting2=value2" ...
apply_fpm_pool_settings() {
local pool_config="$1"
shift
local settings=("$@")
local success_count=0
local failed_count=0
for setting_value in "${settings[@]}"; do
local setting="${setting_value%%=*}"
local value="${setting_value#*=}"
if modify_fpm_pool_setting "$pool_config" "$setting" "$value"; then
success_count=$((success_count + 1))
else
failed_count=$((failed_count + 1))
fi
done
echo "Applied: $success_count settings, $failed_count failed"
if [ "$failed_count" -eq 0 ]; then
return 0
else
return 1
fi
}
# ============================================================================
# PHP-FPM RESTART FUNCTIONS
# ============================================================================
# Restart PHP-FPM service
# Usage: restart_php_fpm <php_version>
restart_php_fpm() {
local php_version="$1" # e.g., "ea-php82" or "82"
# Normalize version format
if [[ ! "$php_version" =~ ^ea-php ]]; then
php_version="ea-php${php_version}"
fi
# Detect init system
if command -v systemctl >/dev/null 2>&1; then
# systemd
local service_name="${php_version}-php-fpm"
systemctl restart "$service_name" 2>/dev/null
if [ $? -eq 0 ]; then
echo "Restarted: $service_name (systemd)"
return 0
else
echo "ERROR: Failed to restart $service_name"
return 1
fi
elif command -v service >/dev/null 2>&1; then
# sysvinit
local service_name="${php_version}-php-fpm"
service "$service_name" restart 2>/dev/null
if [ $? -eq 0 ]; then
echo "Restarted: $service_name (service)"
return 0
else
echo "ERROR: Failed to restart $service_name"
return 1
fi
else
echo "ERROR: Cannot detect init system"
return 1
fi
}
# Reload PHP-FPM service (graceful restart)
# Usage: reload_php_fpm <php_version>
reload_php_fpm() {
local php_version="$1"
# Normalize version format
if [[ ! "$php_version" =~ ^ea-php ]]; then
php_version="ea-php${php_version}"
fi
# Detect init system
if command -v systemctl >/dev/null 2>&1; then
# systemd
local service_name="${php_version}-php-fpm"
systemctl reload "$service_name" 2>/dev/null
if [ $? -eq 0 ]; then
echo "Reloaded: $service_name (graceful)"
return 0
else
# Fallback to restart if reload fails
restart_php_fpm "$php_version"
return $?
fi
else
# Reload not supported, use restart
restart_php_fpm "$php_version"
return $?
fi
}
# Verify PHP-FPM is running
# Usage: verify_php_fpm_running <php_version>
verify_php_fpm_running() {
local php_version="$1"
# Normalize version format
if [[ ! "$php_version" =~ ^ea-php ]]; then
php_version="ea-php${php_version}"
fi
if command -v systemctl >/dev/null 2>&1; then
local service_name="${php_version}-php-fpm"
systemctl is-active "$service_name" >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo "Running: $service_name"
return 0
else
echo "NOT running: $service_name"
return 1
fi
else
# Check process
if pgrep -f "${php_version}-php-fpm" >/dev/null 2>&1; then
echo "Running: ${php_version}-php-fpm"
return 0
else
echo "NOT running: ${php_version}-php-fpm"
return 1
fi
fi
}
# Export all functions
export -f initialize_backup_system
export -f backup_php_config
export -f backup_fpm_pool
export -f backup_user_php_configs
export -f list_backups
export -f restore_php_config
export -f restore_from_backup
export -f delete_backup
export -f modify_fpm_pool_setting
export -f modify_php_ini_setting
export -f apply_fpm_pool_settings
export -f restart_php_fpm
export -f reload_php_fpm
export -f verify_php_fpm_running