mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-10-26 07:46:35 +01:00
366 lines
13 KiB
Python
366 lines
13 KiB
Python
|
|
# -*- coding: utf-8 -*-
|
||
|
|
"""
|
||
|
|
Operating System Configuration for Test Plugin
|
||
|
|
Provides OS-specific configurations and compatibility checks
|
||
|
|
"""
|
||
|
|
import os
|
||
|
|
import platform
|
||
|
|
import subprocess
|
||
|
|
import sys
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
|
||
|
|
class OSConfig:
|
||
|
|
"""Operating System Configuration Manager"""
|
||
|
|
|
||
|
|
def __init__(self):
|
||
|
|
self.os_name = self._detect_os_name()
|
||
|
|
self.os_version = self._detect_os_version()
|
||
|
|
self.os_arch = platform.machine()
|
||
|
|
self.python_path = self._detect_python_path()
|
||
|
|
self.pip_path = self._detect_pip_path()
|
||
|
|
self.service_manager = self._detect_service_manager()
|
||
|
|
self.web_server = self._detect_web_server()
|
||
|
|
self.package_manager = self._detect_package_manager()
|
||
|
|
|
||
|
|
def _detect_os_name(self):
|
||
|
|
"""Detect operating system name"""
|
||
|
|
try:
|
||
|
|
with open('/etc/os-release', 'r') as f:
|
||
|
|
for line in f:
|
||
|
|
if line.startswith('ID='):
|
||
|
|
return line.split('=')[1].strip().strip('"')
|
||
|
|
except FileNotFoundError:
|
||
|
|
pass
|
||
|
|
|
||
|
|
# Fallback detection
|
||
|
|
if os.path.exists('/etc/redhat-release'):
|
||
|
|
return 'rhel'
|
||
|
|
elif os.path.exists('/etc/debian_version'):
|
||
|
|
return 'debian'
|
||
|
|
else:
|
||
|
|
return platform.system().lower()
|
||
|
|
|
||
|
|
def _detect_os_version(self):
|
||
|
|
"""Detect operating system version"""
|
||
|
|
try:
|
||
|
|
with open('/etc/os-release', 'r') as f:
|
||
|
|
for line in f:
|
||
|
|
if line.startswith('VERSION_ID='):
|
||
|
|
return line.split('=')[1].strip().strip('"')
|
||
|
|
except FileNotFoundError:
|
||
|
|
pass
|
||
|
|
|
||
|
|
# Fallback detection
|
||
|
|
if os.path.exists('/etc/redhat-release'):
|
||
|
|
try:
|
||
|
|
with open('/etc/redhat-release', 'r') as f:
|
||
|
|
content = f.read()
|
||
|
|
import re
|
||
|
|
match = re.search(r'(\d+\.\d+)', content)
|
||
|
|
if match:
|
||
|
|
return match.group(1)
|
||
|
|
except:
|
||
|
|
pass
|
||
|
|
|
||
|
|
return platform.release()
|
||
|
|
|
||
|
|
def _detect_python_path(self):
|
||
|
|
"""Detect Python executable path"""
|
||
|
|
# Try different Python commands
|
||
|
|
python_commands = ['python3', 'python3.11', 'python3.10', 'python3.9', 'python3.8', 'python3.7', 'python3.6', 'python']
|
||
|
|
|
||
|
|
for cmd in python_commands:
|
||
|
|
try:
|
||
|
|
result = subprocess.run([cmd, '--version'],
|
||
|
|
capture_output=True, text=True, timeout=5)
|
||
|
|
if result.returncode == 0:
|
||
|
|
# Check if it's Python 3.6+
|
||
|
|
version = result.stdout.strip()
|
||
|
|
if 'Python 3' in version:
|
||
|
|
version_num = version.split()[1]
|
||
|
|
major, minor = map(int, version_num.split('.')[:2])
|
||
|
|
if major == 3 and minor >= 6:
|
||
|
|
return cmd
|
||
|
|
except (subprocess.TimeoutExpired, FileNotFoundError, ValueError):
|
||
|
|
continue
|
||
|
|
|
||
|
|
# Fallback to sys.executable
|
||
|
|
return sys.executable
|
||
|
|
|
||
|
|
def _detect_pip_path(self):
|
||
|
|
"""Detect pip executable path"""
|
||
|
|
# Try different pip commands
|
||
|
|
pip_commands = ['pip3', 'pip3.11', 'pip3.10', 'pip3.9', 'pip3.8', 'pip3.7', 'pip3.6', 'pip']
|
||
|
|
|
||
|
|
for cmd in pip_commands:
|
||
|
|
try:
|
||
|
|
result = subprocess.run([cmd, '--version'],
|
||
|
|
capture_output=True, text=True, timeout=5)
|
||
|
|
if result.returncode == 0:
|
||
|
|
return cmd
|
||
|
|
except (subprocess.TimeoutExpired, FileNotFoundError):
|
||
|
|
continue
|
||
|
|
|
||
|
|
# Fallback
|
||
|
|
return 'pip3'
|
||
|
|
|
||
|
|
def _detect_service_manager(self):
|
||
|
|
"""Detect service manager (systemd, init.d, etc.)"""
|
||
|
|
if os.path.exists('/bin/systemctl') or os.path.exists('/usr/bin/systemctl'):
|
||
|
|
return 'systemctl'
|
||
|
|
elif os.path.exists('/etc/init.d'):
|
||
|
|
return 'service'
|
||
|
|
else:
|
||
|
|
return 'systemctl' # Default to systemctl
|
||
|
|
|
||
|
|
def _detect_web_server(self):
|
||
|
|
"""Detect web server"""
|
||
|
|
if os.path.exists('/etc/apache2') or os.path.exists('/etc/httpd'):
|
||
|
|
if os.path.exists('/etc/apache2'):
|
||
|
|
return 'apache2'
|
||
|
|
else:
|
||
|
|
return 'httpd'
|
||
|
|
else:
|
||
|
|
return 'httpd' # Default
|
||
|
|
|
||
|
|
def _detect_package_manager(self):
|
||
|
|
"""Detect package manager"""
|
||
|
|
if os.path.exists('/usr/bin/dnf'):
|
||
|
|
return 'dnf'
|
||
|
|
elif os.path.exists('/usr/bin/yum'):
|
||
|
|
return 'yum'
|
||
|
|
elif os.path.exists('/usr/bin/apt'):
|
||
|
|
return 'apt'
|
||
|
|
elif os.path.exists('/usr/bin/apt-get'):
|
||
|
|
return 'apt-get'
|
||
|
|
else:
|
||
|
|
return 'unknown'
|
||
|
|
|
||
|
|
def get_os_info(self):
|
||
|
|
"""Get comprehensive OS information"""
|
||
|
|
return {
|
||
|
|
'name': self.os_name,
|
||
|
|
'version': self.os_version,
|
||
|
|
'architecture': self.os_arch,
|
||
|
|
'python_path': self.python_path,
|
||
|
|
'pip_path': self.pip_path,
|
||
|
|
'service_manager': self.service_manager,
|
||
|
|
'web_server': self.web_server,
|
||
|
|
'package_manager': self.package_manager,
|
||
|
|
'platform': platform.platform(),
|
||
|
|
'python_version': sys.version
|
||
|
|
}
|
||
|
|
|
||
|
|
def is_supported_os(self):
|
||
|
|
"""Check if the current OS is supported"""
|
||
|
|
supported_os = [
|
||
|
|
'ubuntu', 'debian', 'almalinux', 'rocky', 'rhel',
|
||
|
|
'centos', 'cloudlinux', 'fedora'
|
||
|
|
]
|
||
|
|
return self.os_name in supported_os
|
||
|
|
|
||
|
|
def get_os_specific_config(self):
|
||
|
|
"""Get OS-specific configuration"""
|
||
|
|
configs = {
|
||
|
|
'ubuntu': {
|
||
|
|
'python_cmd': 'python3',
|
||
|
|
'pip_cmd': 'pip3',
|
||
|
|
'service_cmd': 'systemctl',
|
||
|
|
'web_server': 'apache2',
|
||
|
|
'package_manager': 'apt-get',
|
||
|
|
'cyberpanel_user': 'cyberpanel',
|
||
|
|
'cyberpanel_group': 'cyberpanel'
|
||
|
|
},
|
||
|
|
'debian': {
|
||
|
|
'python_cmd': 'python3',
|
||
|
|
'pip_cmd': 'pip3',
|
||
|
|
'service_cmd': 'systemctl',
|
||
|
|
'web_server': 'apache2',
|
||
|
|
'package_manager': 'apt-get',
|
||
|
|
'cyberpanel_user': 'cyberpanel',
|
||
|
|
'cyberpanel_group': 'cyberpanel'
|
||
|
|
},
|
||
|
|
'almalinux': {
|
||
|
|
'python_cmd': 'python3',
|
||
|
|
'pip_cmd': 'pip3',
|
||
|
|
'service_cmd': 'systemctl',
|
||
|
|
'web_server': 'httpd',
|
||
|
|
'package_manager': 'dnf',
|
||
|
|
'cyberpanel_user': 'cyberpanel',
|
||
|
|
'cyberpanel_group': 'cyberpanel'
|
||
|
|
},
|
||
|
|
'rocky': {
|
||
|
|
'python_cmd': 'python3',
|
||
|
|
'pip_cmd': 'pip3',
|
||
|
|
'service_cmd': 'systemctl',
|
||
|
|
'web_server': 'httpd',
|
||
|
|
'package_manager': 'dnf',
|
||
|
|
'cyberpanel_user': 'cyberpanel',
|
||
|
|
'cyberpanel_group': 'cyberpanel'
|
||
|
|
},
|
||
|
|
'rhel': {
|
||
|
|
'python_cmd': 'python3',
|
||
|
|
'pip_cmd': 'pip3',
|
||
|
|
'service_cmd': 'systemctl',
|
||
|
|
'web_server': 'httpd',
|
||
|
|
'package_manager': 'dnf',
|
||
|
|
'cyberpanel_user': 'cyberpanel',
|
||
|
|
'cyberpanel_group': 'cyberpanel'
|
||
|
|
},
|
||
|
|
'centos': {
|
||
|
|
'python_cmd': 'python3',
|
||
|
|
'pip_cmd': 'pip3',
|
||
|
|
'service_cmd': 'systemctl',
|
||
|
|
'web_server': 'httpd',
|
||
|
|
'package_manager': 'dnf',
|
||
|
|
'cyberpanel_user': 'cyberpanel',
|
||
|
|
'cyberpanel_group': 'cyberpanel'
|
||
|
|
},
|
||
|
|
'cloudlinux': {
|
||
|
|
'python_cmd': 'python3',
|
||
|
|
'pip_cmd': 'pip3',
|
||
|
|
'service_cmd': 'systemctl',
|
||
|
|
'web_server': 'httpd',
|
||
|
|
'package_manager': 'yum',
|
||
|
|
'cyberpanel_user': 'cyberpanel',
|
||
|
|
'cyberpanel_group': 'cyberpanel'
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return configs.get(self.os_name, configs['ubuntu']) # Default to Ubuntu config
|
||
|
|
|
||
|
|
def get_python_requirements(self):
|
||
|
|
"""Get Python requirements for the current OS"""
|
||
|
|
base_requirements = [
|
||
|
|
'Django>=2.2,<4.0',
|
||
|
|
'django-cors-headers',
|
||
|
|
'Pillow',
|
||
|
|
'requests',
|
||
|
|
'psutil'
|
||
|
|
]
|
||
|
|
|
||
|
|
# OS-specific requirements
|
||
|
|
os_requirements = {
|
||
|
|
'ubuntu': [],
|
||
|
|
'debian': [],
|
||
|
|
'almalinux': ['python3-devel', 'gcc'],
|
||
|
|
'rocky': ['python3-devel', 'gcc'],
|
||
|
|
'rhel': ['python3-devel', 'gcc'],
|
||
|
|
'centos': ['python3-devel', 'gcc'],
|
||
|
|
'cloudlinux': ['python3-devel', 'gcc']
|
||
|
|
}
|
||
|
|
|
||
|
|
return base_requirements + os_requirements.get(self.os_name, [])
|
||
|
|
|
||
|
|
def get_install_commands(self):
|
||
|
|
"""Get OS-specific installation commands"""
|
||
|
|
config = self.get_os_specific_config()
|
||
|
|
|
||
|
|
if config['package_manager'] in ['apt-get', 'apt']:
|
||
|
|
return {
|
||
|
|
'update': 'apt-get update',
|
||
|
|
'install_python': 'apt-get install -y python3 python3-pip python3-venv',
|
||
|
|
'install_git': 'apt-get install -y git',
|
||
|
|
'install_curl': 'apt-get install -y curl',
|
||
|
|
'install_dev_tools': 'apt-get install -y build-essential python3-dev'
|
||
|
|
}
|
||
|
|
elif config['package_manager'] == 'dnf':
|
||
|
|
return {
|
||
|
|
'update': 'dnf update -y',
|
||
|
|
'install_python': 'dnf install -y python3 python3-pip python3-devel',
|
||
|
|
'install_git': 'dnf install -y git',
|
||
|
|
'install_curl': 'dnf install -y curl',
|
||
|
|
'install_dev_tools': 'dnf install -y gcc gcc-c++ make python3-devel'
|
||
|
|
}
|
||
|
|
elif config['package_manager'] == 'yum':
|
||
|
|
return {
|
||
|
|
'update': 'yum update -y',
|
||
|
|
'install_python': 'yum install -y python3 python3-pip python3-devel',
|
||
|
|
'install_git': 'yum install -y git',
|
||
|
|
'install_curl': 'yum install -y curl',
|
||
|
|
'install_dev_tools': 'yum install -y gcc gcc-c++ make python3-devel'
|
||
|
|
}
|
||
|
|
else:
|
||
|
|
# Fallback to Ubuntu commands
|
||
|
|
return {
|
||
|
|
'update': 'apt-get update',
|
||
|
|
'install_python': 'apt-get install -y python3 python3-pip python3-venv',
|
||
|
|
'install_git': 'apt-get install -y git',
|
||
|
|
'install_curl': 'apt-get install -y curl',
|
||
|
|
'install_dev_tools': 'apt-get install -y build-essential python3-dev'
|
||
|
|
}
|
||
|
|
|
||
|
|
def validate_environment(self):
|
||
|
|
"""Validate the current environment"""
|
||
|
|
issues = []
|
||
|
|
|
||
|
|
# Check Python version
|
||
|
|
try:
|
||
|
|
result = subprocess.run([self.python_path, '--version'],
|
||
|
|
capture_output=True, text=True, timeout=5)
|
||
|
|
if result.returncode == 0:
|
||
|
|
version = result.stdout.strip()
|
||
|
|
if 'Python 3' in version:
|
||
|
|
version_num = version.split()[1]
|
||
|
|
major, minor = map(int, version_num.split('.')[:2])
|
||
|
|
if major < 3 or (major == 3 and minor < 6):
|
||
|
|
issues.append(f"Python 3.6+ required, found {version}")
|
||
|
|
else:
|
||
|
|
issues.append(f"Python 3 required, found {version}")
|
||
|
|
else:
|
||
|
|
issues.append("Python not found or not working")
|
||
|
|
except Exception as e:
|
||
|
|
issues.append(f"Error checking Python: {e}")
|
||
|
|
|
||
|
|
# Check pip
|
||
|
|
try:
|
||
|
|
result = subprocess.run([self.pip_path, '--version'],
|
||
|
|
capture_output=True, text=True, timeout=5)
|
||
|
|
if result.returncode != 0:
|
||
|
|
issues.append("pip not found or not working")
|
||
|
|
except Exception as e:
|
||
|
|
issues.append(f"Error checking pip: {e}")
|
||
|
|
|
||
|
|
# Check if OS is supported
|
||
|
|
if not self.is_supported_os():
|
||
|
|
issues.append(f"Unsupported operating system: {self.os_name}")
|
||
|
|
|
||
|
|
return issues
|
||
|
|
|
||
|
|
def get_compatibility_info(self):
|
||
|
|
"""Get compatibility information for the current OS"""
|
||
|
|
return {
|
||
|
|
'os_supported': self.is_supported_os(),
|
||
|
|
'python_available': self.python_path is not None,
|
||
|
|
'pip_available': self.pip_path is not None,
|
||
|
|
'service_manager': self.service_manager,
|
||
|
|
'web_server': self.web_server,
|
||
|
|
'package_manager': self.package_manager,
|
||
|
|
'validation_issues': self.validate_environment()
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
# Global instance
|
||
|
|
os_config = OSConfig()
|
||
|
|
|
||
|
|
|
||
|
|
def get_os_config():
|
||
|
|
"""Get the global OS configuration instance"""
|
||
|
|
return os_config
|
||
|
|
|
||
|
|
|
||
|
|
def is_os_supported():
|
||
|
|
"""Check if the current OS is supported"""
|
||
|
|
return os_config.is_supported_os()
|
||
|
|
|
||
|
|
|
||
|
|
def get_python_path():
|
||
|
|
"""Get the Python executable path"""
|
||
|
|
return os_config.python_path
|
||
|
|
|
||
|
|
|
||
|
|
def get_pip_path():
|
||
|
|
"""Get the pip executable path"""
|
||
|
|
return os_config.pip_path
|