{% extends "baseTemplate/index.html" %} {% load i18n %} {% load static %} {% block title %}{% trans "Plugin Development Guide - CyberPanel" %}{% endblock %} {% block header_scripts %} {% endblock %} {% block content %}

{% trans "Plugin Development Documentation" %}

{% trans "Complete guide for developing, installing, and managing CyberPanel plugins" %}

Quick Installation Guide - CyberPanel Test Plugin

๐Ÿš€ One-Command Installation

Install the test plugin with a single command using curl or wget.

๐Ÿ“ฆ Manual Installation

Download and install manually with step-by-step instructions.

โš™๏ธ Easy Management

Simple install/uninstall process with proper cleanup.

One-Command Installation

# Install the test plugin with a single command
curl -sSL https://raw.githubusercontent.com/cyberpanel/testPlugin/main/install.sh | bash

Manual Installation

  1. Download the plugin
    git clone https://github.com/cyberpanel/testPlugin.git
    cd testPlugin
  2. Run the installation script
    chmod +x install.sh
    ./install.sh
  3. Access the plugin
    • URL: https://your-domain:8090/testPlugin/
    • Login with your CyberPanel admin credentials

Features Included

โœ… Enable/Disable Toggle

Toggle the plugin on/off with a beautiful switch

โœ… Test Button

Click to show popup messages from the side

โœ… Settings Page

Configure custom messages and preferences

โœ… Activity Logs

View all plugin activities with filtering

โœ… Inline Integration

Loads within CyberPanel interface

โœ… Responsive Design

Works perfectly on all devices

Uninstallation

# Uninstall the plugin
./install.sh --uninstall

Troubleshooting

If you encounter any issues:

  1. Check CyberPanel logs
    tail -f /home/cyberpanel/logs/cyberpanel.log
  2. Restart CyberPanel services
    systemctl restart lscpd
    systemctl restart cyberpanel
  3. Verify installation
    ls -la /home/cyberpanel/plugins/testPlugin
    ls -la /usr/local/CyberCP/testPlugin
Note: This plugin is designed for testing and development purposes. Always backup your system before installing any plugins.

Getting Started with CyberPanel Plugin Development

๐ŸŽฏ Official Documentation

Based on the official CyberPanel plugin development guide from the CyberPanel team.

๐Ÿ“š Step-by-Step Tutorial

Complete walkthrough from development environment setup to plugin installation.

๐Ÿ”ง Signal Integration

Learn how to hook into CyberPanel events and respond to core functionality.

Source: This guide is based on the official CyberPanel documentation and the beautiful_names plugin repository.

Prerequisites

  • Python - Clear understanding of Python Programming Language
  • Django - Experience with Django framework
  • HTML (Basic) - Basic HTML knowledge
  • CSS (Basic) - Basic CSS knowledge

Note: You can use plain JavaScript in your plugins or any JavaScript framework. You just have to follow the norms of Django framework, because CyberPanel plugin is just another Django app.

Step 1: Set up your Development Environment

Clone CyberPanel Repository

git clone https://github.com/usmannasir/cyberpanel/ --single-branch v1.7.2-plugin

Create a Django App

cd v1.7.2-plugin
django-admin startapp pluginName

Choose your plugin name wisely as it's of great importance. Once the Django app is created, you need to define a meta file for your plugin so that CyberPanel can read information about your plugin.

Create Meta File

cd pluginName
nano meta.xml

Paste the following content in the meta.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<cyberpanelPluginConfig>
  <name>customplugin</name>
  <type>plugin</type>
  <description>Plugin to make custom changes</description>
  <version>0</version>
</cyberpanelPluginConfig>

Step 2: Creating a Signal File and Adjusting Settings

Create Signals File

Create a signals.py file (you can name it anything, but signals.py is recommended). You can leave this file empty for now.

Configure apps.py

In your apps.py file, you need to import the signals file inside the ready function:

def ready(self):
    import signals

Configure __init__.py

You need to specify a default_app_config variable in this file:

default_app_config = 'examplePlugin.apps.ExamplepluginConfig'

Create urls.py

Inside your app root directory, create urls.py and paste this content:

from django.conf.urls import url
import views

urlpatterns = [
    url(r'^$', views.examplePlugin, name='examplePlugin'),
]

Important: Replace examplePlugin with your plugin name. This URL definition is very important for CyberPanel to register your plugin page.

Optional Files

You can create these optional files for database model management:

  • pre_install - Executed before installation of plugin
  • post_install - Executed after installation of plugin

If your file is Python code, don't forget to include this line at the top:

#!/usr/local/CyberCP/bin/python2

Step 3: Responding to Events

To plug into events fired by CyberPanel core, you can respond to various events happening in the core. Visit the signal file documentation for a complete list of events.

Example Events

  • preWebsiteCreation - Fired before CyberPanel starts the creation of website
  • postWebsiteDeletion - Fired after core finished the deletion of website

Responding to Events

Here's how you can respond to the postWebsiteDeletion event:

from django.dispatch import receiver
from django.http import HttpResponse
from websiteFunctions.signals import postWebsiteDeletion
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging

@receiver(postWebsiteDeletion)
def rcvr(sender, **kwargs):
    request = kwargs['request']
    logging.writeToFile('Hello World from Example Plugin.')
    return HttpResponse('Hello World from Example Plugin.')

Return Values

  • HttpResponse object - CyberPanel core will stop further processing and return your response to browser
  • int 200 - CyberPanel core will continue processing, assuming the event was successfully executed

Step 4: Packing, Shipping and Installing Plugin

Package Your Plugin

After completing your plugin, zip your Django app. The zip file name should be your plugin name (e.g., examplePlugin.zip), otherwise installation will fail.

Installation

First, upload your plugin to /usr/local/CyberCP/pluginInstaller:

cd /usr/local/CyberCP/pluginInstaller
python pluginInstaller.py install --pluginName examplePlugin

Uninstall

cd /usr/local/CyberCP/pluginInstaller
python pluginInstaller.py remove --pluginName examplePlugin

Beautiful Names Plugin Example

CyberPanel has released an official plugin called Beautiful Names that removes the admin_ prefix from Package and FTP account names. This plugin serves as a great example of how to create CyberPanel plugins.

Installation of Beautiful Names

cd /usr/local/CyberCP/pluginInstaller
wget https://cyberpanel.net/beautifulNames.zip
python pluginInstaller.py install --pluginName beautifulNames

Uninstall Beautiful Names

cd /usr/local/CyberCP/pluginInstaller
python pluginInstaller.py remove --pluginName beautifulNames

Plugin Installation Facility

The plugin installation facility is in beta and not available with the official install yet. To install plugins, you need to install CyberPanel via the test version:

sh <(curl https://mirror.cyberpanel.net/install-test.sh || wget -O - https://mirror.cyberpanel.net/install-test.sh)

Additional Resources

Note: This guide is based on the official CyberPanel documentation. For the most up-to-date information, always refer to the official sources.

CyberPanel Plugin Development Guide

How to Install Plugins

Method 1: Using the Installation Script (Recommended)

# Download and run the installation script
curl -sSL https://raw.githubusercontent.com/cyberpanel/testPlugin/main/install.sh | bash

# Or download first, then run
wget https://raw.githubusercontent.com/cyberpanel/testPlugin/main/install.sh
chmod +x install.sh
./install.sh

Method 2: Manual Installation

  1. Create Plugin Directory Structure
    mkdir -p /home/cyberpanel/plugins/yourPlugin
    mkdir -p /usr/local/CyberCP/yourPlugin
  2. Copy Plugin Files
    cp -r yourPlugin/* /usr/local/CyberCP/yourPlugin/
    chown -R cyberpanel:cyberpanel /usr/local/CyberCP/yourPlugin
    chmod -R 755 /usr/local/CyberCP/yourPlugin
  3. Create Symlink
    ln -sf /usr/local/CyberCP/yourPlugin /home/cyberpanel/plugins/yourPlugin
  4. Update Django Settings

    Add your plugin to INSTALLED_APPS in /usr/local/CyberCP/cyberpanel/settings.py:

    INSTALLED_APPS = [
        # ... existing apps ...
        'yourPlugin',
    ]
  5. Update URL Configuration

    Add your plugin URLs in /usr/local/CyberCP/cyberpanel/urls.py:

    urlpatterns = [
        # ... existing patterns ...
        path("yourPlugin/", include("yourPlugin.urls")),
    ]
  6. Run Migrations
    cd /usr/local/CyberCP
    python3 manage.py makemigrations yourPlugin
    python3 manage.py migrate yourPlugin
  7. Collect Static Files
    python3 manage.py collectstatic --noinput
  8. Restart Services
    systemctl restart lscpd
    systemctl restart cyberpanel

How to Uninstall Plugins

Method 1: Using the Installation Script

# Run with uninstall flag
./install.sh --uninstall

Method 2: Manual Uninstallation

  1. Remove Plugin Files
    rm -rf /usr/local/CyberCP/yourPlugin
    rm -f /home/cyberpanel/plugins/yourPlugin
  2. Remove from Django Settings
    sed -i '/yourPlugin/d' /usr/local/CyberCP/cyberpanel/settings.py
  3. Remove from URLs
    sed -i '/yourPlugin/d' /usr/local/CyberCP/cyberpanel/urls.py
  4. Restart Services
    systemctl restart lscpd
    systemctl restart cyberpanel

How to Add meta.xml

Create a meta.xml file in your plugin root directory:

<?xml version="1.0" encoding="UTF-8"?>
<plugin>
    <name>Your Plugin Name</name>
    <type>Utility</type>
    <description>Your plugin description</description>
    <version>1.0.0</version>
    <author>Your Name</author>
    <website>https://your-website.com</website>
    <license>MIT</license>
    <dependencies>
        <python>3.6+</python>
        <django>2.2+</django>
    </dependencies>
    <permissions>
        <admin>true</admin>
        <user>false</user>
    </permissions>
    <settings>
        <enable_toggle>true</enable_toggle>
        <test_button>true</test_button>
        <popup_messages>true</popup_messages>
        <inline_integration>true</inline_integration>
    </settings>
</plugin>

Required Fields:

  • name: Plugin display name
  • type: Plugin category (Utility, Security, Performance, etc.)
  • description: Plugin description
  • version: Plugin version

Optional Fields:

  • author: Plugin author
  • website: Plugin website
  • license: License type
  • dependencies: Required dependencies
  • permissions: Access permissions
  • settings: Plugin-specific settings

How to Add Buttons for Pages

1. In Your Template

<!-- Primary Action Button -->
<button class="btn-test" id="your-button">
    <i class="fas fa-icon"></i>
    Button Text
</button>

<!-- Secondary Button -->
<a href="{% url 'yourPlugin:your_view' %}" class="btn-secondary">
    <i class="fas fa-icon"></i>
    Button Text
</a>

<!-- Danger Button -->
<button class="btn-danger" id="danger-button">
    <i class="fas fa-trash"></i>
    Delete
</button>

2. CSS Styles

.btn-test {
    background: linear-gradient(135deg, #5856d6, #4a90e2);
    color: white;
    border: none;
    padding: 12px 24px;
    border-radius: 8px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease;
    display: flex;
    align-items: center;
    gap: 8px;
}

.btn-test:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba(88,86,214,0.3);
}

.btn-test:disabled {
    opacity: 0.6;
    cursor: not-allowed;
    transform: none;
}

3. JavaScript Event Handling

document.getElementById('your-button').addEventListener('click', function() {
    // Your button logic here
    fetch('/yourPlugin/your-endpoint/', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRFToken': getCSRFToken()
        },
        body: JSON.stringify({data: 'value'})
    })
    .then(response => response.json())
    .then(data => {
        if (data.status === 1) {
            showNotification('success', 'Success', data.message);
        } else {
            showNotification('error', 'Error', data.error_message);
        }
    });
});

How to Add Toggles

1. HTML Structure

<div class="control-group">
    <label for="plugin-toggle" class="toggle-label">
        Enable Feature
    </label>
    <label class="toggle-switch">
        <input type="checkbox" id="plugin-toggle" {% if feature_enabled %}checked{% endif %}>
        <span class="slider"></span>
    </label>
</div>

2. CSS Styles

.toggle-switch {
    position: relative;
    display: inline-block;
    width: 60px;
    height: 34px;
}

.toggle-switch input {
    opacity: 0;
    width: 0;
    height: 0;
}

.slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #ccc;
    transition: .4s;
    border-radius: 34px;
}

.slider:before {
    position: absolute;
    content: "";
    height: 26px;
    width: 26px;
    left: 4px;
    bottom: 4px;
    background-color: white;
    transition: .4s;
    border-radius: 50%;
    box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}

input:checked + .slider {
    background-color: #5856d6;
}

input:checked + .slider:before {
    transform: translateX(26px);
}

3. JavaScript Handling

document.getElementById('plugin-toggle').addEventListener('change', function() {
    fetch('/yourPlugin/toggle/', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRFToken': getCSRFToken()
        }
    })
    .then(response => response.json())
    .then(data => {
        if (data.status === 1) {
            showNotification('success', 'Toggle Updated', data.message);
        } else {
            showNotification('error', 'Error', data.error_message);
            // Revert toggle state
            this.checked = !this.checked;
        }
    });
});

How to Add Install/Uninstall Buttons

1. In Your Plugin Template

<div class="plugin-actions">
    <button class="btn-install" id="install-plugin">
        <i class="fas fa-download"></i>
        Install Plugin
    </button>
    
    <button class="btn-uninstall" id="uninstall-plugin">
        <i class="fas fa-trash"></i>
        Uninstall Plugin
    </button>
</div>

2. CSS Styles

.plugin-actions {
    display: flex;
    gap: 10px;
    margin-top: 20px;
}

.btn-install {
    background: #10b981;
    color: white;
    border: none;
    padding: 10px 20px;
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.3s ease;
}

.btn-uninstall {
    background: #ef4444;
    color: white;
    border: none;
    padding: 10px 20px;
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.3s ease;
}

.btn-install:hover {
    background: #059669;
    transform: translateY(-2px);
}

.btn-uninstall:hover {
    background: #dc2626;
    transform: translateY(-2px);
}

3. JavaScript Implementation

// Install button
document.getElementById('install-plugin').addEventListener('click', function() {
    if (confirm('Are you sure you want to install this plugin?')) {
        this.disabled = true;
        this.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Installing...';
        
        fetch('/yourPlugin/install/', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-CSRFToken': getCSRFToken()
            }
        })
        .then(response => response.json())
        .then(data => {
            if (data.status === 1) {
                showNotification('success', 'Installation Complete', data.message);
                location.reload();
            } else {
                showNotification('error', 'Installation Failed', data.error_message);
            }
        })
        .finally(() => {
            this.disabled = false;
            this.innerHTML = '<i class="fas fa-download"></i> Install Plugin';
        });
    }
});

// Uninstall button
document.getElementById('uninstall-plugin').addEventListener('click', function() {
    if (confirm('Are you sure you want to uninstall this plugin? This action cannot be undone.')) {
        this.disabled = true;
        this.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Uninstalling...';
        
        fetch('/yourPlugin/uninstall/', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-CSRFToken': getCSRFToken()
            }
        })
        .then(response => response.json())
        .then(data => {
            if (data.status === 1) {
                showNotification('success', 'Uninstallation Complete', data.message);
                setTimeout(() => location.reload(), 2000);
            } else {
                showNotification('error', 'Uninstallation Failed', data.error_message);
            }
        })
        .finally(() => {
            this.disabled = false;
            this.innerHTML = '<i class="fas fa-trash"></i> Uninstall Plugin';
        });
    }
});

How to Add Enable/Disable Plugin Buttons

1. Model for Plugin State

# models.py
from django.db import models
from django.contrib.auth.models import User

class PluginSettings(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    plugin_enabled = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    class Meta:
        unique_together = ['user']

2. View for Toggle

# views.py
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from .models import PluginSettings

@require_http_methods(["POST"])
def toggle_plugin(request):
    try:
        settings, created = PluginSettings.objects.get_or_create(
            user=request.user,
            defaults={'plugin_enabled': True}
        )
        
        settings.plugin_enabled = not settings.plugin_enabled
        settings.save()
        
        return JsonResponse({
            'status': 1,
            'enabled': settings.plugin_enabled,
            'message': f'Plugin {"enabled" if settings.plugin_enabled else "disabled"} successfully'
        })
    except Exception as e:
        return JsonResponse({'status': 0, 'error_message': str(e)})

3. Template Implementation

<div class="plugin-controls">
    <label for="plugin-toggle" class="toggle-label">
        Enable Plugin
    </label>
    <label class="toggle-switch">
        <input type="checkbox" id="plugin-toggle" {% if plugin_enabled %}checked{% endif %}>
        <span class="slider"></span>
    </label>
</div>

4. JavaScript Handling

document.getElementById('plugin-toggle').addEventListener('change', function() {
    fetch('/yourPlugin/toggle/', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRFToken': getCSRFToken()
        }
    })
    .then(response => response.json())
    .then(data => {
        if (data.status === 1) {
            showNotification('success', 'Plugin Toggle', data.message);
            // Update UI elements based on enabled state
            updatePluginUI(data.enabled);
        } else {
            showNotification('error', 'Error', data.error_message);
            this.checked = !this.checked; // Revert toggle
        }
    });
});

function updatePluginUI(enabled) {
    const buttons = document.querySelectorAll('.plugin-button');
    buttons.forEach(button => {
        button.disabled = !enabled;
    });
    
    const statusIndicator = document.querySelector('.status-indicator');
    if (statusIndicator) {
        statusIndicator.textContent = enabled ? 'Enabled' : 'Disabled';
        statusIndicator.className = `status-indicator ${enabled ? 'enabled' : 'disabled'}`;
    }
}

How to Avoid Breaking the CyberPanel Sidebar

1. Use CyberPanel's Base Template

Always extend the base template:

{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% load static %}

{% block title %}{% trans "Your Plugin - CyberPanel" %}{% endblock %}

{% block content %}
<!-- Your plugin content here -->
{% endblock %}

2. Don't Modify the Sidebar HTML

Never directly modify the sidebar HTML. Instead, use CyberPanel's built-in navigation system.

3. Use Proper CSS Scoping

/* Good: Scoped to your plugin */
.your-plugin-wrapper {
    /* Your styles here */
}

/* Bad: Global styles that might affect sidebar */
.sidebar {
    /* Don't do this */
}

4. Use CyberPanel's CSS Variables

.your-plugin-element {
    background: var(--bg-primary, white);
    color: var(--text-primary, #2f3640);
    border: 1px solid var(--border-primary, #e8e9ff);
}

5. Test Responsive Design

Ensure your plugin works on all screen sizes without breaking the sidebar:

@media (max-width: 768px) {
    .your-plugin-wrapper {
        padding: 15px;
    }
    
    /* Don't modify sidebar behavior */
}

How to Make Plugins Load Inline

1. Use CyberPanel's httpProc

# views.py
from plogical.httpProc import httpProc

def your_view(request):
    context = {
        'data': 'your_data',
        'plugin_enabled': True
    }
    
    proc = httpProc(request, 'yourPlugin/your_template.html', context, 'admin')
    return proc.render()

2. Template Structure

{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% load static %}

{% block title %}{% trans "Your Plugin - CyberPanel" %}{% endblock %}

{% block header_scripts %}
<style>
    /* Your plugin-specific styles */
    .your-plugin-wrapper {
        background: transparent;
        padding: 20px;
    }
    
    .your-plugin-container {
        max-width: 1200px;
        margin: 0 auto;
    }
</style>
{% endblock %}

{% block content %}
<div class="your-plugin-wrapper">
    <div class="your-plugin-container">
        <!-- Your plugin content here -->
    </div>
</div>
{% endblock %}

3. URL Configuration

# urls.py
from django.urls import path
from . import views

app_name = 'yourPlugin'

urlpatterns = [
    path('', views.your_view, name='your_view'),
    path('settings/', views.settings_view, name='settings'),
    # ... other URLs
]

4. Main URLs Integration

# In /usr/local/CyberCP/cyberpanel/urls.py
urlpatterns = [
    # ... existing patterns ...
    path("yourPlugin/", include("yourPlugin.urls")),
]

Plugin Structure Overview

yourPlugin/
โ”œโ”€โ”€ __init__.py
โ”œโ”€โ”€ admin.py
โ”œโ”€โ”€ apps.py
โ”œโ”€โ”€ models.py
โ”œโ”€โ”€ views.py
โ”œโ”€โ”€ urls.py
โ”œโ”€โ”€ signals.py
โ”œโ”€โ”€ meta.xml
โ”œโ”€โ”€ install.sh
โ”œโ”€โ”€ templates/
โ”‚   โ””โ”€โ”€ yourPlugin/
โ”‚       โ”œโ”€โ”€ plugin_home.html
โ”‚       โ”œโ”€โ”€ plugin_settings.html
โ”‚       โ””โ”€โ”€ plugin_logs.html
โ”œโ”€โ”€ static/
โ”‚   โ””โ”€โ”€ yourPlugin/
โ”‚       โ”œโ”€โ”€ css/
โ”‚       โ”‚   โ””โ”€โ”€ yourPlugin.css
โ”‚       โ””โ”€โ”€ js/
โ”‚           โ””โ”€โ”€ yourPlugin.js
โ””โ”€โ”€ migrations/
    โ””โ”€โ”€ __init__.py

Best Practices

1. Security

  • Always validate user input
  • Use CSRF protection
  • Sanitize data before displaying
  • Use proper authentication decorators

2. Performance

  • Use database indexes for frequently queried fields
  • Implement caching where appropriate
  • Optimize database queries
  • Minimize JavaScript and CSS

3. User Experience

  • Provide clear feedback for all actions
  • Use loading states for long operations
  • Implement proper error handling
  • Make the interface responsive

4. Code Quality

  • Follow Django best practices
  • Use meaningful variable names
  • Add proper documentation
  • Write unit tests

5. Integration

  • Use CyberPanel's existing components
  • Follow the established design patterns
  • Maintain consistency with the UI
  • Test thoroughly before release

Troubleshooting

Common Issues

1. Plugin not showing in installed plugins

  • Check if meta.xml exists and is valid
  • Verify the plugin is in INSTALLED_APPS
  • Ensure proper file permissions

2. Template not found errors

  • Check template path in views.py
  • Verify template files exist
  • Ensure proper directory structure

3. Static files not loading

  • Run python3 manage.py collectstatic
  • Check STATIC_URL configuration
  • Verify file permissions

4. Database migration errors

  • Check model definitions
  • Run python3 manage.py makemigrations
  • Verify database connectivity

5. Permission denied errors

  • Check file ownership (cyberpanel:cyberpanel)
  • Verify file permissions (755 for directories, 644 for files)
  • Ensure proper SELinux context if applicable

Debug Steps

1. Check CyberPanel logs

tail -f /home/cyberpanel/logs/cyberpanel.log

2. Check Django logs

tail -f /home/cyberpanel/logs/django.log

3. Verify plugin installation

ls -la /home/cyberpanel/plugins/
ls -la /usr/local/CyberCP/yourPlugin/

4. Test database connectivity

cd /usr/local/CyberCP
python3 manage.py shell

5. Check service status

systemctl status lscpd
systemctl status cyberpanel
Conclusion: This guide provides comprehensive instructions for developing CyberPanel plugins. Follow the best practices and troubleshooting steps to ensure your plugins integrate seamlessly with CyberPanel while maintaining security and performance standards.

Operating System Compatibility

๐ŸŒ Multi-OS Support

Comprehensive support for all CyberPanel-supported operating systems.

๐Ÿ” Automatic Detection

Intelligent OS detection and configuration for seamless installation.

๐Ÿงช Compatibility Testing

Built-in compatibility testing to verify system requirements.

Supported Operating Systems

Ubuntu

  • โœ… Ubuntu 22.04 (Full Support)
  • โœ… Ubuntu 20.04 (Full Support)
  • โœ… Debian 11+ (Compatible)

Package Manager: apt-get

Web Server: apache2

RHEL-based

  • โœ… AlmaLinux 8, 9, 10
  • โœ… RockyLinux 8, 9
  • โœ… RHEL 8, 9
  • โœ… CentOS 9

Package Manager: dnf/yum

Web Server: httpd

CloudLinux

  • โœ… CloudLinux 8
  • โœ… CloudLinux 7 (Limited)

Package Manager: yum

Web Server: httpd

Python Compatibility

The plugin requires Python 3.6+ and automatically detects the correct Python executable:

# Detection order:
1. python3.12
2. python3.11
3. python3.10
4. python3.9
5. python3.8
6. python3.7
7. python3.6
8. python3
9. python (fallback)

Installation Compatibility

The installation script automatically detects your operating system and configures the plugin accordingly:

# Automatic detection includes:
- OS name and version
- Python executable path
- Package manager (apt-get, dnf, yum)
- Service manager (systemctl, service)
- Web server (apache2, httpd)
- User and group permissions

Compatibility Testing

Run the built-in compatibility test to verify your system:

# Navigate to plugin directory
cd /usr/local/CyberCP/testPlugin

# Run compatibility test
python3 test_os_compatibility.py

# Or make it executable and run
chmod +x test_os_compatibility.py
./test_os_compatibility.py

Test Results

The compatibility test checks:

OS-Specific Configurations

Ubuntu/Debian Systems

# Package Manager: apt-get
# Python: python3
# Pip: pip3
# Service Manager: systemctl
# Web Server: apache2
# User/Group: cyberpanel:cyberpanel

# Installation commands
sudo apt-get update
sudo apt-get install -y python3 python3-pip python3-venv git curl
sudo apt-get install -y build-essential python3-dev

RHEL-based Systems

# Package Manager: dnf (RHEL 8+) / yum (RHEL 7)
# Python: python3
# Pip: pip3
# Service Manager: systemctl
# Web Server: httpd
# User/Group: cyberpanel:cyberpanel

# Installation commands (RHEL 8+)
sudo dnf install -y python3 python3-pip python3-devel git curl
sudo dnf install -y gcc gcc-c++ make

# Installation commands (RHEL 7)
sudo yum install -y python3 python3-pip python3-devel git curl
sudo yum install -y gcc gcc-c++ make

CloudLinux

# Package Manager: yum
# Python: python3
# Pip: pip3
# Service Manager: systemctl
# Web Server: httpd
# User/Group: cyberpanel:cyberpanel

# Installation commands
sudo yum install -y python3 python3-pip python3-devel git curl
sudo yum install -y gcc gcc-c++ make

# CageFS configuration
cagefsctl --enable cyberpanel
cagefsctl --update

Security Compatibility

SELinux (RHEL-based systems)

# Check SELinux status
sestatus

# Set proper context for plugin files
setsebool -P httpd_can_network_connect 1
chcon -R -t httpd_exec_t /usr/local/CyberCP/testPlugin/

AppArmor (Ubuntu/Debian)

# Check AppArmor status
aa-status

# Allow Apache to access plugin files
aa-complain apache2

Firewall Configuration

# Ubuntu/Debian (ufw)
sudo ufw allow 8090/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# RHEL-based (firewalld)
sudo firewall-cmd --permanent --add-port=8090/tcp
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --reload

Troubleshooting

Common Issues

Python not found

# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y python3 python3-pip

# RHEL-based
sudo dnf install -y python3 python3-pip
# or
sudo yum install -y python3 python3-pip

Permission denied

sudo chown -R cyberpanel:cyberpanel /home/cyberpanel/plugins
sudo chown -R cyberpanel:cyberpanel /usr/local/CyberCP/testPlugin

Service not starting

sudo systemctl daemon-reload
sudo systemctl restart lscpd
sudo systemctl restart apache2  # Ubuntu/Debian
sudo systemctl restart httpd    # RHEL-based

Debug Commands

# Check OS information
cat /etc/os-release
uname -a

# Check Python installation
python3 --version
which python3
which pip3

# Check services
systemctl status lscpd
systemctl status apache2  # Ubuntu/Debian
systemctl status httpd    # RHEL-based

# Check file permissions
ls -la /home/cyberpanel/plugins/
ls -la /usr/local/CyberCP/testPlugin/

# Check CyberPanel logs
tail -f /home/cyberpanel/logs/cyberpanel.log
tail -f /home/cyberpanel/logs/django.log
Note: The plugin is designed to work seamlessly across all supported operating systems. If you encounter any compatibility issues, please run the compatibility test and check the troubleshooting section above.
{% endblock %}