diff --git a/to-do/PAID-PLUGINS-GUIDE.md b/to-do/PAID-PLUGINS-GUIDE.md deleted file mode 100644 index 146ee81f1..000000000 --- a/to-do/PAID-PLUGINS-GUIDE.md +++ /dev/null @@ -1,214 +0,0 @@ -# Paid Plugins Support for CyberPanel - -## Overview - -CyberPanel now supports paid plugins that require Patreon subscription. Users can install paid plugins, but they cannot run them without an active Patreon subscription to the specified tier. - -## Features - -- ✅ Paid plugin detection from `meta.xml` -- ✅ Patreon subscription verification -- ✅ Installable but non-functional without subscription -- ✅ Visual indicators (badges) for paid plugins in all views: - - Grid View: Green "Free" or Yellow "Paid" badge next to version - - Table View: Green "Free" or Yellow "Paid" badge next to version - - Store View: Separate "Pricing" column with Free/Paid badges -- ✅ Subscription required page when accessing without subscription -- ✅ "Subscribe on Patreon" button in subscription warning -- ✅ API endpoint for checking subscription status - -## Plugin Structure - -### Meta.xml for Paid Plugins - -Add the following fields to your plugin's `meta.xml`: - -```xml -true -CyberPanel Paid Plugin -https://www.patreon.com/membership/27789984 -``` - -### Example meta.xml - -```xml - - - Premium Plugin Example - Utility - 1.0.0 - An example paid plugin - master3395 - true - CyberPanel Paid Plugin - https://www.patreon.com/membership/27789984 - /plugins/premiumPlugin/ - /plugins/premiumPlugin/settings/ - -``` - -## Implementation in Plugin Views - -### Using the Premium Plugin Decorator - -```python -from pluginHolder.plugin_access import check_plugin_access - -def premium_plugin_required(view_func): - """ - Decorator that checks if user has Patreon subscription - """ - @wraps(view_func) - def _wrapped_view(request, *args, **kwargs): - # Check login first - try: - userID = request.session['userID'] - except KeyError: - from loginSystem.views import loadLoginPage - return redirect(loadLoginPage) - - # Check plugin access - plugin_meta = { - 'is_paid': True, - 'patreon_tier': 'CyberPanel Paid Plugin', - 'patreon_url': 'https://www.patreon.com/c/newstargeted/membership' - } - - access_check = check_plugin_access(request, 'yourPluginName', plugin_meta) - - if not access_check['has_access']: - # Show subscription required page - context = { - 'plugin_name': 'Your Plugin Name', - 'is_paid': True, - 'patreon_tier': access_check.get('patreon_tier', 'CyberPanel Paid Plugin'), - 'patreon_url': access_check.get('patreon_url'), - 'message': access_check.get('message', 'Patreon subscription required') - } - proc = httpProc(request, 'yourPlugin/subscription_required.html', context, 'admin') - return proc.render() - - # User has access - proceed - return view_func(request, *args, **kwargs) - - return _wrapped_view - -@cyberpanel_login_required -@premium_plugin_required -def your_view(request): - # Your view code here - pass -``` - -## Patreon Configuration - -### Environment Variables - -Set the following environment variables in CyberPanel: - -```bash -export PATREON_CLIENT_ID="your_client_id" -export PATREON_CLIENT_SECRET="your_client_secret" -export PATREON_CREATOR_ID="your_creator_id" -``` - -Or add them to `/usr/local/CyberCP/CyberCP/settings.py`: - -```python -import os - -PATREON_CLIENT_ID = os.environ.get('PATREON_CLIENT_ID', '') -PATREON_CLIENT_SECRET = os.environ.get('PATREON_CLIENT_SECRET', '') -PATREON_CREATOR_ID = os.environ.get('PATREON_CREATOR_ID', '') -``` - -### User Token Storage - -Users need to authorize CyberPanel to check their Patreon membership. Tokens are stored in: - -``` -/home/cyberpanel/patreon_tokens/{user_email}.token -``` - -## API Endpoints - -### Check Subscription Status - -``` -GET /plugins/api/check-subscription// -``` - -Response: -```json -{ - "success": true, - "has_access": true, - "is_paid": true, - "message": "Access granted", - "patreon_url": null -} -``` - -## Example Plugin - -A complete example paid plugin is available at: - -``` -/home/cyberpanel-plugins/premiumPlugin/ -``` - -This plugin demonstrates: -- Paid plugin meta.xml structure -- Subscription verification -- Subscription required page -- Protected views - -## User Experience - -### For Users Without Subscription - -1. Plugin appears in installed plugins list with "Premium" badge and "Paid" pricing badge -2. Plugin appears in CyberPanel Plugin Store with "Paid" badge in the Pricing column -3. Plugin can be installed -4. When accessing plugin, subscription required page is shown -5. Link to Patreon subscription page is provided with "Subscribe on Patreon" button - -### For Users With Subscription - -1. Plugin works normally -2. All features are accessible -3. Settings page is available -4. No restrictions - -## Files Created/Modified - -### New Files - -- `/home/cyberpanel-repo/pluginHolder/patreon_verifier.py` - Patreon API integration -- `/home/cyberpanel-repo/pluginHolder/plugin_access.py` - Plugin access control -- `/home/cyberpanel-plugins/premiumPlugin/` - Example paid plugin - -### Modified Files - -- `/home/cyberpanel-repo/pluginHolder/views.py` - Added paid plugin parsing and subscription check API -- `/home/cyberpanel-repo/pluginHolder/templates/pluginHolder/plugins.html` - Added paid plugin badges and warnings -- `/home/cyberpanel-repo/pluginHolder/urls.py` - Added subscription check endpoint - -## Testing - -1. Install the example premium plugin -2. Try accessing it without subscription (should show subscription required page) -3. Subscribe to Patreon tier "CyberPanel Paid Plugin" -4. Authorize CyberPanel to check membership -5. Access plugin again (should work normally) - -## Notes - -- Subscription checks are cached for 5 minutes to reduce API calls -- Users must authorize CyberPanel to check their Patreon membership -- The system checks for the exact tier name specified in `patreon_tier` -- Free plugins work normally without any changes - -## Author - -master3395 diff --git a/to-do/PATREON-CONFIGURATION.md b/to-do/PATREON-CONFIGURATION.md deleted file mode 100644 index c29697ce5..000000000 --- a/to-do/PATREON-CONFIGURATION.md +++ /dev/null @@ -1,58 +0,0 @@ -# Patreon Configuration for CyberPanel Paid Plugins - -## Configuration Complete - -Patreon credentials have been configured in CyberPanel settings. - -### Credentials Configuration - -**SECURITY WARNING**: Never commit secrets to the repository! - -Set these via environment variables: - -```bash -export PATREON_CLIENT_ID="your_client_id_here" -export PATREON_CLIENT_SECRET="your_client_secret_here" -export PATREON_MEMBERSHIP_TIER_ID="your_tier_id_here" -export PATREON_CREATOR_ACCESS_TOKEN="your_access_token_here" -export PATREON_CREATOR_REFRESH_TOKEN="your_refresh_token_here" -``` - -Or add to `/etc/environment` or systemd service file. - -### Location - -Credentials are stored in: -- `/usr/local/CyberCP/CyberCP/settings.py` (or `/home/cyberpanel-repo/CyberCP/settings.py`) - -### How It Works - -1. Users install paid plugins (no subscription required) -2. When accessing the plugin, system checks for Patreon membership -3. If user has active subscription to tier `27789984`, access is granted -4. If not, subscription required page is shown - -### Testing - -To test the configuration: - -1. Install the `premiumPlugin` example plugin -2. Try accessing it without subscription (should show subscription page) -3. Subscribe to Patreon tier "CyberPanel Paid Plugin" (ID: 27789984) -4. Authorize CyberPanel to check membership -5. Access plugin again (should work) - -### Membership Verification - -The system checks for: -- Tier ID: `27789984` -- Tier Name: "CyberPanel Paid Plugin" (fallback) -- Active patron status -- Currently entitled amount > 0 - -### Notes - -- Membership checks are cached for 5 minutes -- Users must authorize CyberPanel via OAuth to check membership -- Creator access token can be used for server-side verification - diff --git a/to-do/PATREON-SETUP-SECURE.md b/to-do/PATREON-SETUP-SECURE.md deleted file mode 100644 index 0779e3601..000000000 --- a/to-do/PATREON-SETUP-SECURE.md +++ /dev/null @@ -1,115 +0,0 @@ -# Secure Patreon Configuration Setup - -## ⚠️ SECURITY WARNING - -**NEVER commit Patreon secrets to the repository!** - -All secrets must be configured via environment variables on the production server. - -## Setup Instructions - -### 1. Get Your Patreon Credentials - -From your Patreon Developer Dashboard: -- Client ID -- Client Secret -- Membership Tier ID (e.g., `27789984`) -- Creator Access Token (optional, for server-side verification) -- Creator Refresh Token (optional) - -### 2. Configure Environment Variables - -#### Option A: Systemd Service (Recommended) - -Edit `/etc/systemd/system/lscpd.service`: - -```ini -[Service] -Environment="PATREON_CLIENT_ID=your_client_id" -Environment="PATREON_CLIENT_SECRET=your_client_secret" -Environment="PATREON_MEMBERSHIP_TIER_ID=your_tier_id" -Environment="PATREON_CREATOR_ACCESS_TOKEN=your_access_token" -Environment="PATREON_CREATOR_REFRESH_TOKEN=your_refresh_token" -``` - -Then reload and restart: -```bash -systemctl daemon-reload -systemctl restart lscpd -``` - -#### Option B: /etc/environment - -Add to `/etc/environment`: -```bash -PATREON_CLIENT_ID=your_client_id -PATREON_CLIENT_SECRET=your_client_secret -PATREON_MEMBERSHIP_TIER_ID=your_tier_id -PATREON_CREATOR_ACCESS_TOKEN=your_access_token -PATREON_CREATOR_REFRESH_TOKEN=your_refresh_token -``` - -#### Option C: Secure Config File (Not in Repo) - -Create `/usr/local/CyberCP/patreon_config.py` (add to .gitignore): - -```python -# Patreon Configuration - DO NOT COMMIT TO REPOSITORY -PATREON_CLIENT_ID = 'your_client_id' -PATREON_CLIENT_SECRET = 'your_client_secret' -PATREON_MEMBERSHIP_TIER_ID = 'your_tier_id' -PATREON_CREATOR_ACCESS_TOKEN = 'your_access_token' -PATREON_CREATOR_REFRESH_TOKEN = 'your_refresh_token' -``` - -Then import in settings.py: -```python -try: - from .patreon_config import * -except ImportError: - pass # Use environment variables instead -``` - -### 3. Verify Configuration - -Test that secrets are loaded: -```bash -python3 -c " -import os -print('Client ID:', 'SET' if os.environ.get('PATREON_CLIENT_ID') else 'NOT SET') -print('Client Secret:', 'SET' if os.environ.get('PATREON_CLIENT_SECRET') else 'NOT SET') -print('Tier ID:', os.environ.get('PATREON_MEMBERSHIP_TIER_ID', 'NOT SET')) -" -``` - -### 4. Security Checklist - -- [ ] Secrets removed from repository -- [ ] Environment variables set on production server -- [ ] `/usr/local/CyberCP/patreon_config.py` added to .gitignore (if used) -- [ ] CyberPanel service restarted -- [ ] Configuration verified working - -## For Plugin Developers - -When creating paid plugins: - -1. **Never hardcode secrets** in plugin code -2. **Use environment variables** or Django settings -3. **Document required variables** in README -4. **Provide example** with placeholder values only - -Example meta.xml: -```xml -true -Your Tier Name -https://www.patreon.com/c/yourname/membership -``` - -## Troubleshooting - -If membership checks fail: -1. Verify environment variables are set: `env | grep PATREON` -2. Check CyberPanel logs: `/home/lscp/logs/error.log` -3. Verify tier ID matches your Patreon tier -4. Ensure user has authorized OAuth access diff --git a/to-do/REMOTE-VERIFICATION-ARCHITECTURE.md b/to-do/REMOTE-VERIFICATION-ARCHITECTURE.md deleted file mode 100644 index 053149677..000000000 --- a/to-do/REMOTE-VERIFICATION-ARCHITECTURE.md +++ /dev/null @@ -1,89 +0,0 @@ -# Remote Verification Architecture for Paid Plugins - -## Problem - -When users install plugins, they can see all files on their system, which could expose: -- Patreon API credentials -- Verification logic -- Access tokens - -## Solution: Remote Verification Server - -Move all Patreon verification to **YOUR server** (not the user's server). - -### Architecture - -``` -User's Server (Plugin) Your Server Patreon API - | | | - |-- Verify Request ----------->| | - | |-- Check Membership --->| - | |<-- Membership Status --| - |<-- Access Granted/Denied ----| | -``` - -### Benefits - -1. **No secrets on user's server** - All credentials stay on your server -2. **Users can't intercept** - Verification happens server-to-server -3. **Centralized control** - You can revoke access, update logic, etc. -4. **Plugin code can be public** - Only makes API calls, no secrets - -## Implementation - -### 1. Your Verification Server - -Create an API endpoint on your server (e.g., `api.newstargeted.com`): - -```python -# Your server endpoint: /api/verify-patreon-membership -POST /api/verify-patreon-membership -{ - "user_email": "user@example.com", - "plugin_name": "premiumPlugin", - "tier_id": "27789984" -} - -Response: -{ - "has_access": true, - "expires_at": "2026-02-25T00:00:00Z" -} -``` - -### 2. Plugin Code (Public, No Secrets) - -The plugin only makes HTTP requests to your server: - -```python -def check_remote_membership(user_email, plugin_name): - response = requests.post( - 'https://api.newstargeted.com/api/verify-patreon-membership', - json={ - 'user_email': user_email, - 'plugin_name': plugin_name, - 'tier_id': '27789984' - }, - headers={'X-Plugin-Version': '1.0.0'} - ) - return response.json() -``` - -### 3. Security Measures - -- **Rate limiting** - Prevent abuse -- **IP whitelisting** - Only allow from CyberPanel servers (optional) -- **Plugin signature** - Verify requests come from legitimate plugins -- **Caching** - Reduce API calls to Patreon -- **HTTPS only** - Encrypt all communication - -## Alternative: Encrypted Plugin Package - -If you want to encrypt the entire plugin: - -1. **Encrypt plugin files** before distribution -2. **Decrypt on install** using a license key -3. **License key** tied to user's Patreon subscription -4. **Your server** generates license keys - -This is more complex but provides stronger protection. diff --git a/to-do/REMOTE-VERIFICATION-COMPLETE.md b/to-do/REMOTE-VERIFICATION-COMPLETE.md deleted file mode 100644 index 2012db765..000000000 --- a/to-do/REMOTE-VERIFICATION-COMPLETE.md +++ /dev/null @@ -1,115 +0,0 @@ -# Remote Verification Setup Complete ✅ - -## Summary - -All components are now set up for secure remote verification of paid plugins. Users can install plugins and see all code, but **NO secrets are exposed** because all Patreon API calls happen on YOUR server. - -## ✅ What Was Completed - -### 1. Remote Verification API -- **Endpoint**: `https://api.newstargeted.com/api/verify-patreon-membership` -- **Location**: `/home/newstargeted.com/api.newstargeted.com/api/verify-patreon-membership.php` -- **Status**: ✅ Working and tested -- **Permissions**: ✅ newst3922:newst3922 (644) - -### 2. Plugin Updated -- **File**: `/home/cyberpanel-plugins/premiumPlugin/views.py` -- **Method**: Remote verification (no secrets) -- **Status**: ✅ Updated and tested -- **Permissions**: ✅ newst3922:newst3922 (644) - -### 3. Configuration -- **Patreon credentials**: Added to `/home/newstargeted.com/api.newstargeted.com/config.php` -- **Permissions**: ✅ 600 (secure, readable only by owner) -- **Owner**: ✅ newst3922:newst3922 - -### 4. Routing -- **.htaccess**: Updated with API routing rules -- **API Router**: Created at `/api/index.php` -- **Status**: ✅ Working - -## 🔒 Security Features - -✅ **No secrets in plugin** - All code is public-safe -✅ **Credentials on your server only** - Never exposed to users -✅ **Rate limiting** - 60 requests/hour per IP -✅ **Caching** - 5 minute cache to reduce API calls -✅ **HTTPS only** - All communication encrypted -✅ **Proper permissions** - Config files protected (600) - -## 📁 File Permissions Summary - -### API Files -- `/home/newstargeted.com/api.newstargeted.com/api/verify-patreon-membership.php`: 644, newst3922:newst3922 -- `/home/newstargeted.com/api.newstargeted.com/api/index.php`: 644, newst3922:newst3922 -- `/home/newstargeted.com/api.newstargeted.com/config.php`: 600, newst3922:newst3922 (secure) -- `/home/newstargeted.com/api.newstargeted.com/.htaccess`: 644, newst3922:newst3922 - -### Plugin Files -- `/home/cyberpanel-plugins/premiumPlugin/`: All files 644, directories 755, newst3922:newst3922 -- `/home/cyberpanel/plugins/premiumPlugin/`: All files 644, directories 755, newst3922:newst3922 - -## 🧪 Testing - -### API Endpoint Test -```bash -curl -X POST https://api.newstargeted.com/api/verify-patreon-membership \ - -H "Content-Type: application/json" \ - -d '{"user_email":"test@example.com","plugin_name":"premiumPlugin","tier_id":"27789984"}' -``` - -**Result**: ✅ Returns proper JSON response - -### Plugin Test -1. Install plugin from CyberPanel -2. Try accessing plugin -3. Should show subscription required page (if not subscribed) -4. Plugin makes API call to your server (no secrets exposed) - -## 📋 Next Steps - -1. **Implement OAuth Flow** (optional but recommended) - - Users authorize CyberPanel via Patreon OAuth - - Store access tokens securely (database recommended) - - Link tokens to user emails - -2. **Test Full Flow** - - Subscribe to Patreon tier - - Authorize CyberPanel - - Access plugin (should work) - -3. **Monitor** - - Check API logs for errors - - Monitor rate limiting - - Verify caching is working - -## 🎯 Plugin is Safe to Publish - -The `premiumPlugin` can now be: -- ✅ Published to public repositories -- ✅ Shared with users -- ✅ Installed on any server -- ✅ Code reviewed by anyone - -**No secrets will be exposed** because all verification happens on your server! - -## 📝 Files Created/Modified - -### Created -- `/home/newstargeted.com/api.newstargeted.com/api/verify-patreon-membership.php` -- `/home/newstargeted.com/api.newstargeted.com/api/index.php` -- `/home/cyberpanel-plugins/premiumPlugin/views.py` (remote version) -- `/home/cyberpanel-plugins/premiumPlugin/SECURITY.md` - -### Modified -- `/home/newstargeted.com/api.newstargeted.com/config.php` (added Patreon credentials) -- `/home/newstargeted.com/api.newstargeted.com/.htaccess` (added API routing) -- `/home/cyberpanel-plugins/premiumPlugin/views.py` (updated to remote verification) - -## ✨ Benefits - -1. **Security**: Secrets never leave your server -2. **Control**: You can revoke access, update logic centrally -3. **Transparency**: Plugin code can be open source -4. **Scalability**: Centralized verification handles all requests -5. **Maintenance**: Update verification logic in one place diff --git a/to-do/SETUP-COMPLETE.md b/to-do/SETUP-COMPLETE.md deleted file mode 100644 index c344e6eb1..000000000 --- a/to-do/SETUP-COMPLETE.md +++ /dev/null @@ -1,86 +0,0 @@ -# Remote Verification Setup Complete ✅ - -## What Was Done - -### 1. Remote Verification API Created -- **Location**: `/home/newstargeted.com/api.newstargeted.com/modules/patreon/verify-membership.php` -- **URL**: `https://api.newstargeted.com/api/verify-patreon-membership` -- **Route**: Added to `.htaccess` for clean URL routing - -### 2. Plugin Updated to Use Remote Verification -- **File**: `/home/cyberpanel-plugins/premiumPlugin/views.py` -- **Method**: All Patreon checks now go through your server -- **No Secrets**: Plugin code contains zero credentials - -### 3. Configuration Added -- **Patreon credentials** added to `/home/newstargeted.com/api.newstargeted.com/config.php` -- **Secure permissions**: config.php set to 600 (readable only by owner) - -### 4. File Permissions Set -- ✅ API files: `newst3922:newst3922` (644 for files, 755 for directories) -- ✅ Plugin files: `newst3922:newst3922` (644 for files, 755 for directories) -- ✅ Config file: `newst3922:newst3922` (600 - secure) - -## Security Features - -✅ **No secrets in plugin** - Users can see all code -✅ **All credentials on your server** - Never exposed -✅ **Rate limiting** - 60 requests/hour per IP -✅ **Caching** - 5 minute cache to reduce API calls -✅ **HTTPS only** - All communication encrypted -✅ **Error handling** - Graceful failures - -## How It Works - -1. User installs plugin (no subscription needed) -2. User tries to access plugin -3. Plugin makes API call to YOUR server -4. Your server checks Patreon API (credentials stay on your server) -5. Your server returns access status -6. Plugin shows content or subscription page - -## Testing - -### Test API Endpoint -```bash -curl -X POST https://api.newstargeted.com/api/verify-patreon-membership \ - -H "Content-Type: application/json" \ - -d '{ - "user_email": "test@example.com", - "plugin_name": "premiumPlugin", - "tier_id": "27789984" - }' -``` - -### Expected Response -```json -{ - "success": true, - "has_access": false, - "patreon_tier": "CyberPanel Paid Plugin", - "patreon_url": "https://www.patreon.com/c/newstargeted/membership", - "message": "Patreon subscription required..." -} -``` - -## Next Steps - -1. **Test the API endpoint** - Verify it's accessible -2. **Implement OAuth flow** - For users to authorize Patreon access -3. **Store user tokens** - Link Patreon tokens to user emails -4. **Test full flow** - Install plugin and verify access control - -## Files Modified - -- `/home/newstargeted.com/api.newstargeted.com/config.php` - Added Patreon credentials -- `/home/newstargeted.com/api.newstargeted.com/.htaccess` - Added API route -- `/home/newstargeted.com/api.newstargeted.com/modules/patreon/verify-membership.php` - Created -- `/home/cyberpanel-plugins/premiumPlugin/views.py` - Updated to use remote verification -- `/home/cyberpanel/plugins/premiumPlugin/views.py` - Updated (installed version) - -## Plugin is Now Safe to Publish - -✅ No secrets in code -✅ All verification happens on your server -✅ Users can see all plugin files without security risk -✅ Centralized control and updates diff --git a/to-do/v2.5.5-dev-installation-fixes.md b/to-do/v2.5.5-dev-installation-fixes.md deleted file mode 100644 index 23cdc92c5..000000000 --- a/to-do/v2.5.5-dev-installation-fixes.md +++ /dev/null @@ -1,132 +0,0 @@ -# CyberPanel v2.5.5-dev Installation Fixes - -## Issues Identified - -### Issue 1: install.sh Module Loading Failure -**Problem**: When executing `install.sh` via `sh <(curl ...)`, the script tries to load modules from `/dev/fd/.../modules/` which doesn't exist because the script is executed directly from stdin. - -**Error Message**: -``` -❌ Module not found: /dev/fd/modules/os/detect.sh -❌ Failed to load OS detection module -``` - -**Root Cause**: The script assumes it's running from a cloned repository directory, but when executed via curl, `SCRIPT_DIR` becomes `/dev/fd/...` which doesn't contain the modules. - -### Issue 2: MariaDB 10.x to 12.x Upgrade Blocked -**Problem**: The installer attempts to install MariaDB 12.1 on systems that already have MariaDB 10.11.15 installed. MariaDB's package pre-installation script blocks the upgrade because direct upgrades from 10.x to 12.x are not safe without manual dump/restore. - -**Error Message**: -``` -error: %prein(MariaDB-server-12.1.2-1.el9.x86_64) scriptlet failed, exit status 1 -Error in PREIN scriptlet in rpm package MariaDB-server -``` - -**Root Cause**: The installer doesn't check for existing MariaDB installations before attempting to install MariaDB 12.1. - -## Fixes Implemented - -### Fix 1: install.sh - Handle Curl/Wget Execution - -**Location**: `install/install.sh` - -**Changes**: -1. Added detection for curl/wget execution (checks if `SCRIPT_DIR` is `/dev/fd/*` or modules directory doesn't exist) -2. When detected, the script now: - - Clones the CyberPanel repository to a temporary directory - - Extracts branch name from command-line arguments - - Falls back to legacy installer if git clone fails -3. Properly handles branch argument parsing for both `-b` and `--branch` flags - -**Code Added**: -```bash -# Check if script is being executed via curl/wget -if [[ "$SCRIPT_DIR" == /dev/fd/* ]] || [[ ! -d "$SCRIPT_DIR/modules" ]]; then - # Clone repository first - # ... (see install.sh for full implementation) -fi -``` - -### Fix 2: install.py - MariaDB Installation Detection and Upgrade Attempt - -**Location**: `install/install.py` - -**Changes**: -1. Added `checkExistingMariaDB()` method that: - - Checks for installed MariaDB/MySQL server packages (RPM or DEB) - - Detects MariaDB data directory existence - - Extracts version information from `mysql --version` output - - Returns version info including major.minor version - -2. Added `_attemptMariaDBUpgrade()` method that: - - Attempts to install MariaDB 12.1 on systems with MariaDB 10.x - - Sets up MariaDB 12.1 repository - - Attempts installation with appropriate flags (`--allowerasing` for RHEL) - - Returns `True` if successful, `False` if blocked or fails - - Handles upgrade restriction errors gracefully - -3. Modified `installMySQL()` method to: - - Check for existing MariaDB installation before attempting install - - **If MariaDB 10.x is detected**: Attempt to upgrade to 12.1 first - - If upgrade succeeds: Use new MariaDB 12.1 installation - - If upgrade fails/blocked: Fall back to existing MariaDB 10.x - - If MariaDB 12.x or higher is detected: Skip installation and use existing - - Only attempt new installation if no MariaDB is found - -**Key Logic**: -```python -# Check if MariaDB is already installed -is_installed, installed_version, major_minor = self.checkExistingMariaDB() - -if is_installed: - if major_minor and major_minor != "unknown": - major_ver = float(major_minor) - if major_ver < 12.0: - # Try to upgrade to 12.1 first - upgrade_success = self._attemptMariaDBUpgrade() - if upgrade_success: - # Use new MariaDB 12.1 - return True - else: - # Fall back to existing MariaDB 10.x - self.startMariaDB() - return True - # Use existing MariaDB 12.x+ installation - self.startMariaDB() - return True -``` - -## Testing Recommendations - -1. **Test install.sh with curl**: - ```bash - sh <(curl -s https://raw.githubusercontent.com/master3395/cyberpanel/v2.5.5-dev/install.sh) - ``` - -2. **Test on AlmaLinux 9 with existing MariaDB 10.x**: - - System should detect existing MariaDB 10.x - - Should attempt to upgrade to MariaDB 12.1 first - - If upgrade is blocked, should fall back to using existing MariaDB 10.x - - Should log appropriate messages about upgrade attempt and fallback - -3. **Test on clean AlmaLinux 9 system**: - - Should install MariaDB 12.1 successfully - - Should complete full installation - -## Files Modified - -1. `install/install.sh` - Added curl/wget execution handling -2. `install/install.py` - Added MariaDB detection and existing installation handling - -## Notes - -- The installer now **attempts to upgrade MariaDB 10.x to 12.1 first**, and only falls back to using existing 10.x if the upgrade is blocked by the package manager -- This provides the best of both worlds: tries to get the latest version, but safely falls back if upgrade restrictions prevent it -- The upgrade attempt uses `--allowerasing` flag for RHEL-based systems to allow package replacements -- If MariaDB's pre-installation scriptlet blocks the upgrade (as it does for 10.x to 12.x), the installer gracefully falls back to the existing installation -- The curl/wget execution now properly clones the repository before attempting to load modules - -## Related Issues - -- MariaDB 10.x to 12.x upgrades require manual dump/restore per MariaDB documentation -- The installer now respects existing installations to prevent data loss