mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2026-05-09 17:35:37 +02:00
33
.github/scripts/ci-validate-upgrade.sh
vendored
Executable file
33
.github/scripts/ci-validate-upgrade.sh
vendored
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
# Run inside CI Docker container (or repo root). Validates upgrade loader + modules and key files.
|
||||
set -e
|
||||
|
||||
echo "=== Shell syntax check ==="
|
||||
for f in cyberpanel_upgrade.sh preUpgrade.sh fix-phpmyadmin.sh cyberpanel.sh cyberpanel_utility.sh; do
|
||||
[ ! -f "$f" ] && continue
|
||||
bash -n "$f" || { echo "FAIL (syntax): $f"; exit 1; }
|
||||
echo "OK $f"
|
||||
done
|
||||
test -f preUpgrade.sh && test -f cyberpanel_upgrade.sh || { echo "Missing required scripts"; exit 1; }
|
||||
|
||||
echo "=== Key files ==="
|
||||
for f in preUpgrade.sh cyberpanel_upgrade.sh plogical/upgrade.py install/install.py; do
|
||||
test -f "$f" || { echo "Missing: $f"; exit 1; }
|
||||
done
|
||||
grep -q 'BRANCH_NAME' preUpgrade.sh || exit 1
|
||||
|
||||
if [ -d upgrade_modules ]; then
|
||||
for n in 00_common 01_variables 02_checks 03_mariadb 04_git_url 05_repository 06_components 07_branch_input 08_main_upgrade 09_sync 10_post_tweak 11_display_final; do
|
||||
test -f "upgrade_modules/${n}.sh" || { echo "Missing: upgrade_modules/${n}.sh"; exit 1; }
|
||||
done
|
||||
grep -q 'Branch_Check\|Branch_Name' upgrade_modules/00_common.sh upgrade_modules/02_checks.sh || exit 1
|
||||
grep -q 'upgrade_modules\|Pre_Upgrade_Branch_Input\|Set_Default_Variables' cyberpanel_upgrade.sh || exit 1
|
||||
for f in upgrade_modules/*.sh; do
|
||||
[ -f "$f" ] || continue
|
||||
bash -n "$f" || { echo "FAIL (syntax): $f"; exit 1; }
|
||||
done
|
||||
else
|
||||
grep -q 'Branch_Name\|download_install_phpmyadmin\|Branch_Check' cyberpanel_upgrade.sh || exit 1
|
||||
fi
|
||||
|
||||
echo "Done."
|
||||
109
.github/workflows/ci.yml
vendored
109
.github/workflows/ci.yml
vendored
@@ -1,6 +1,7 @@
|
||||
# Lightweight CI for v2.5.5-dev (free for public repos).
|
||||
# Validates shell syntax, Python version fetcher, and key files on all supported OSes via Docker.
|
||||
# CloudLinux and RHEL use Rocky/Alma images as proxies (same family, no official Docker images).
|
||||
# Validates shell syntax, Python version fetcher, key files, and upgrade script.
|
||||
# Pinned to ubuntu-22.04. Multi-OS validation: run locally with
|
||||
# for img in almalinux:8 centos:7 debian:12 ubuntu:24.04; do docker run --rm -v "$PWD:/repo:ro" -w /repo $img bash /repo/.github/scripts/ci-validate-upgrade.sh; done
|
||||
name: CI
|
||||
|
||||
on:
|
||||
@@ -12,7 +13,7 @@ on:
|
||||
jobs:
|
||||
validate-shell:
|
||||
name: Validate shell scripts
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Syntax check shell scripts
|
||||
@@ -23,11 +24,20 @@ jobs:
|
||||
echo "OK $f"
|
||||
done
|
||||
test -f preUpgrade.sh && test -f cyberpanel_upgrade.sh || { echo "Missing required scripts"; exit 1; }
|
||||
if [ -d upgrade_modules ]; then
|
||||
echo "=== Upgrade modules syntax ==="
|
||||
for f in upgrade_modules/*.sh; do
|
||||
[ -f "$f" ] || continue
|
||||
bash -n "$f" || { echo "FAIL (syntax): $f"; exit 1; }
|
||||
echo "OK $f"
|
||||
done
|
||||
fi
|
||||
echo "All shell scripts passed syntax check"
|
||||
|
||||
validate-python:
|
||||
name: Validate Python (version fetcher)
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 2
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
@@ -37,6 +47,10 @@ jobs:
|
||||
run: pip install requests
|
||||
- name: Run version fetcher (phpMyAdmin / SnappyMail)
|
||||
run: |
|
||||
if [ ! -f plogical/versionFetcher.py ]; then
|
||||
echo "Skipping (plogical/versionFetcher.py not present on this branch)"
|
||||
exit 0
|
||||
fi
|
||||
PYTHONPATH=. python3 -c "
|
||||
from plogical.versionFetcher import get_latest_phpmyadmin_version, get_latest_snappymail_version
|
||||
pma = get_latest_phpmyadmin_version()
|
||||
@@ -48,79 +62,38 @@ jobs:
|
||||
|
||||
smoke-key-files:
|
||||
name: Key files present
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Check key install/upgrade files exist
|
||||
run: |
|
||||
for f in preUpgrade.sh cyberpanel_upgrade.sh plogical/upgrade.py install/install.py plogical/versionFetcher.py; do
|
||||
for f in preUpgrade.sh cyberpanel_upgrade.sh plogical/upgrade.py install/install.py; do
|
||||
test -f "$f" || { echo "Missing: $f"; exit 1; }
|
||||
done
|
||||
test -f plogical/versionFetcher.py && echo "versionFetcher.py present" || echo "versionFetcher.py optional (not on all branches)"
|
||||
grep -q 'BRANCH_NAME' preUpgrade.sh || exit 1
|
||||
grep -q 'Branch_Name\|download_install_phpmyadmin\|Branch_Check' cyberpanel_upgrade.sh || exit 1
|
||||
if [ -d upgrade_modules ]; then
|
||||
for n in 00_common 01_variables 02_checks 03_mariadb 04_git_url 05_repository 06_components 07_branch_input 08_main_upgrade 09_sync 10_post_tweak 11_display_final; do
|
||||
test -f "upgrade_modules/${n}.sh" || { echo "Missing: upgrade_modules/${n}.sh"; exit 1; }
|
||||
done
|
||||
grep -q 'Branch_Check\|Branch_Name' upgrade_modules/00_common.sh upgrade_modules/02_checks.sh || exit 1
|
||||
grep -q 'upgrade_modules\|Pre_Upgrade_Branch_Input\|Set_Default_Variables' cyberpanel_upgrade.sh || exit 1
|
||||
else
|
||||
grep -q 'Branch_Name\|download_install_phpmyadmin\|Branch_Check' cyberpanel_upgrade.sh || exit 1
|
||||
fi
|
||||
echo "Key files OK"
|
||||
|
||||
# Run validation inside a container per supported OS (AlmaLinux, CentOS, CloudLinux, Debian, RHEL, Rocky, Ubuntu).
|
||||
validate-on-os:
|
||||
name: Validate on ${{ matrix.os }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: AlmaLinux 8
|
||||
image: almalinux:8
|
||||
- os: AlmaLinux 9
|
||||
image: almalinux:9
|
||||
- os: AlmaLinux 10
|
||||
image: almalinux:10
|
||||
- os: CentOS 7
|
||||
image: centos:7
|
||||
- os: CloudLinux 8
|
||||
image: rockylinux:8
|
||||
- os: CloudLinux 9
|
||||
image: rockylinux:9
|
||||
- os: Debian 11
|
||||
image: debian:11
|
||||
- os: Debian 12
|
||||
image: debian:12
|
||||
- os: Debian 13
|
||||
image: debian:13
|
||||
- os: RHEL 8
|
||||
image: almalinux:8
|
||||
- os: RHEL 9
|
||||
image: almalinux:9
|
||||
- os: RockyLinux 8
|
||||
image: rockylinux:8
|
||||
- os: RockyLinux 9
|
||||
image: rockylinux:9
|
||||
- os: Ubuntu 20.04
|
||||
image: ubuntu:20.04
|
||||
- os: Ubuntu 22.04
|
||||
image: ubuntu:22.04
|
||||
- os: Ubuntu 24.04
|
||||
image: ubuntu:24.04
|
||||
# Run upgrade validation script (same checks as other jobs; no Docker to avoid runner issues).
|
||||
validate-upgrade-script:
|
||||
name: Validate upgrade script
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Validate on ${{ matrix.os }} (${{ matrix.image }})
|
||||
- name: Run ci-validate-upgrade.sh
|
||||
run: |
|
||||
docker run --rm \
|
||||
-v "$PWD:/repo:ro" \
|
||||
-w /repo \
|
||||
"${{ matrix.image }}" \
|
||||
bash -c '
|
||||
set -e
|
||||
echo "=== Shell syntax check ==="
|
||||
for f in cyberpanel_upgrade.sh preUpgrade.sh fix-phpmyadmin.sh cyberpanel.sh cyberpanel_utility.sh; do
|
||||
[ ! -f "$f" ] && continue
|
||||
bash -n "$f" || { echo "FAIL (syntax): $f"; exit 1; }
|
||||
echo "OK $f"
|
||||
done
|
||||
test -f preUpgrade.sh && test -f cyberpanel_upgrade.sh || { echo "Missing required scripts"; exit 1; }
|
||||
echo "=== Key files ==="
|
||||
for f in preUpgrade.sh cyberpanel_upgrade.sh plogical/upgrade.py install/install.py plogical/versionFetcher.py; do
|
||||
test -f "$f" || { echo "Missing: $f"; exit 1; }
|
||||
done
|
||||
grep -q "BRANCH_NAME" preUpgrade.sh && grep -q "Branch_Name\|download_install_phpmyadmin\|Branch_Check" cyberpanel_upgrade.sh || exit 1
|
||||
echo "Done."
|
||||
'
|
||||
set -e
|
||||
if [ ! -f .github/scripts/ci-validate-upgrade.sh ]; then
|
||||
echo "Missing .github/scripts/ci-validate-upgrade.sh"
|
||||
exit 1
|
||||
fi
|
||||
bash .github/scripts/ci-validate-upgrade.sh
|
||||
|
||||
@@ -209,6 +209,9 @@ STATIC_ROOT = os.path.join(BASE_DIR, "static/")
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
# Panel public directory (SnappyMail, phpMyAdmin, etc.) – served so /snappymail/ and /phpmyadmin/ work when panel is behind Django
|
||||
PUBLIC_ROOT = os.path.join(BASE_DIR, 'public')
|
||||
|
||||
LOCALE_PATHS = (
|
||||
os.path.join(BASE_DIR, 'locale'),
|
||||
)
|
||||
@@ -247,4 +250,25 @@ LOGIN_REDIRECT_URL = '/'
|
||||
|
||||
# Default primary key field type
|
||||
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||
|
||||
# Sync INSTALLED_APPS with plugins on disk so /plugins/<name>/ and /plugins/<name>/settings/ work.
|
||||
# Plugins installed under /usr/local/CyberCP/ (or BASE_DIR) are added here if they have meta.xml + urls.py.
|
||||
_cybercp_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
if os.path.isdir(_cybercp_root):
|
||||
try:
|
||||
_existing_apps = set(INSTALLED_APPS)
|
||||
for _name in os.listdir(_cybercp_root):
|
||||
if _name.startswith('.'):
|
||||
continue
|
||||
_plugin_dir = os.path.join(_cybercp_root, _name)
|
||||
if not os.path.isdir(_plugin_dir):
|
||||
continue
|
||||
if _name in _existing_apps:
|
||||
continue
|
||||
if (os.path.exists(os.path.join(_plugin_dir, 'meta.xml')) and
|
||||
os.path.exists(os.path.join(_plugin_dir, 'urls.py'))):
|
||||
INSTALLED_APPS.append(_name)
|
||||
_existing_apps.add(_name)
|
||||
except (OSError, IOError):
|
||||
pass
|
||||
File diff suppressed because it is too large
Load Diff
2211
cyberpanel_upgrade_monolithic.sh
Normal file
2211
cyberpanel_upgrade_monolithic.sh
Normal file
File diff suppressed because it is too large
Load Diff
@@ -47,7 +47,8 @@ try {
|
||||
|
||||
$username = htmlspecialchars($_POST['username'], ENT_QUOTES, 'UTF-8');
|
||||
$password = $_POST['password'];
|
||||
$host = isset($_POST['host']) ? trim($_POST['host']) : 'localhost';
|
||||
$host = isset($_POST['host']) ? trim($_POST['host']) : '127.0.0.1';
|
||||
if ($host === 'localhost') { $host = '127.0.0.1'; }
|
||||
|
||||
$_SESSION['PMA_single_signon_user'] = $username;
|
||||
$_SESSION['PMA_single_signon_password'] = $password;
|
||||
|
||||
@@ -1262,6 +1262,8 @@ $cfg['Servers'][$i]['auth_type'] = 'signon';
|
||||
$cfg['Servers'][$i]['SignonSession'] = 'SignonSession';
|
||||
$cfg['Servers'][$i]['SignonURL'] = 'phpmyadminsignin.php';
|
||||
$cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout';
|
||||
$cfg['Servers'][$i]['host'] = '127.0.0.1';
|
||||
$cfg['Servers'][$i]['port'] = '3306';
|
||||
"""
|
||||
|
||||
for items in data:
|
||||
@@ -1295,8 +1297,10 @@ $cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout';
|
||||
|
||||
mysqluser = jsonData['mysqluser']
|
||||
mysqlpassword = jsonData['mysqlpassword']
|
||||
mysqlport = jsonData['mysqlport']
|
||||
mysqlhost = jsonData['mysqlhost']
|
||||
mysqlport = jsonData.get('mysqlport', 3306)
|
||||
mysqlhost = jsonData.get('mysqlhost', '127.0.0.1') or '127.0.0.1'
|
||||
if mysqlhost == 'localhost':
|
||||
mysqlhost = '127.0.0.1'
|
||||
|
||||
command = "sed -i 's|localhost|%s|g' /usr/local/CyberCP/public/phpmyadmin/phpmyadminsignin.php" % (
|
||||
mysqlhost)
|
||||
|
||||
@@ -430,13 +430,20 @@
|
||||
.installed-sort-filter-bar {
|
||||
flex-basis: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
margin-top: 12px;
|
||||
padding: 12px 0;
|
||||
border-top: 1px solid var(--border-primary, #e2e8f0);
|
||||
}
|
||||
.installed-sort-filter-bar .installed-filter-row,
|
||||
.installed-sort-filter-bar .installed-sort-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
.installed-sort-filter-bar .sort-label {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
@@ -819,6 +826,82 @@
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
/* Collapsible Category Filter for Grid/Table (installed view) - same style as A-Å filter */
|
||||
.installed-category-filter-wrapper {
|
||||
margin-top: 12px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.installed-category-toggle-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 16px;
|
||||
border: 1px solid var(--border-primary, #e8e9ff);
|
||||
background: var(--bg-primary, white);
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--text-secondary, #64748b);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.installed-category-toggle-btn:hover {
|
||||
background: var(--bg-hover, #f8f9ff);
|
||||
border-color: #5856d6;
|
||||
color: #5856d6;
|
||||
}
|
||||
.installed-category-toggle-btn[aria-expanded="true"] .installed-category-chevron {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
.installed-category-chevron {
|
||||
font-size: 10px;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
.installed-category-filter {
|
||||
display: block;
|
||||
margin-top: 12px;
|
||||
padding: 15px;
|
||||
background: var(--bg-secondary, #f8f9ff);
|
||||
border-radius: 8px;
|
||||
}
|
||||
.installed-category-filter .installed-filter-row,
|
||||
.installed-category-filter .installed-sort-row {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.installed-category-filter .installed-sort-row:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.installed-category-filter-btns {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.installed-category-btn {
|
||||
padding: 6px 12px;
|
||||
border: 1px solid var(--border-primary, #e8e9ff);
|
||||
background: var(--bg-primary, white);
|
||||
border-radius: 6px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
color: var(--text-secondary, #64748b);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.installed-category-btn:hover {
|
||||
background: var(--bg-hover, #f0f1ff);
|
||||
border-color: #5856d6;
|
||||
color: #5856d6;
|
||||
}
|
||||
.installed-category-btn.active {
|
||||
background: #5856d6;
|
||||
color: white;
|
||||
border-color: #5856d6;
|
||||
}
|
||||
|
||||
.alpha-btn {
|
||||
padding: 6px 12px;
|
||||
border: 1px solid var(--border-primary, #e8e9ff);
|
||||
@@ -1224,21 +1307,58 @@
|
||||
{% trans "Plugin Development Guide" %}
|
||||
</a>
|
||||
</div>
|
||||
<!-- Sort bar for Grid and Table view (visible when grid or table is active) -->
|
||||
<!-- Filter + Sort bar for Grid and Table view (visible when grid or table is active). All controls in collapsible "Filter". -->
|
||||
<div id="installedSortFilterBar" class="installed-sort-filter-bar" style="display: none;"
|
||||
data-trans-name-asc="{% trans 'Name A-Å' %}" data-trans-name-desc="{% trans 'Name Å-A' %}"
|
||||
data-trans-date-newest="{% trans 'Date (newest)' %}" data-trans-date-oldest="{% trans 'Date (oldest)' %}">
|
||||
<span class="sort-label">{% trans "Sort by:" %}</span>
|
||||
<div class="sort-btns">
|
||||
<button type="button" class="sort-btn active" data-sort-field="name" id="installedSortBtnName" onclick="toggleInstalledSort('name')" title="{% trans 'Click to toggle A-Å / Å-A' %}">
|
||||
<i class="fas fa-sort-alpha-down"></i> <span class="sort-btn-label">{% trans "Name A-Å" %}</span>
|
||||
</button>
|
||||
<button type="button" class="sort-btn" data-sort-field="type" id="installedSortBtnType" onclick="toggleInstalledSort('type')" title="{% trans 'By category/type' %}">
|
||||
<i class="fas fa-tag"></i> <span class="sort-btn-label">{% trans "Type" %}</span>
|
||||
</button>
|
||||
<button type="button" class="sort-btn" data-sort-field="date" id="installedSortBtnDate" onclick="toggleInstalledSort('date')" title="{% trans 'Click to toggle newest / oldest' %}">
|
||||
<i class="fas fa-calendar-alt"></i> <span class="sort-btn-label">{% trans "Date (newest)" %}</span>
|
||||
data-trans-date-newest="{% trans 'Date (newest)' %}" data-trans-date-oldest="{% trans 'Date (oldest)' }}">
|
||||
<div class="installed-category-filter-wrapper">
|
||||
<button type="button" class="installed-category-toggle-btn" id="installedCategoryToggleBtn" onclick="toggleInstalledCategoryFilter()" aria-expanded="false">
|
||||
<i class="fas fa-filter"></i>
|
||||
<span>{% trans "Filter" %}</span>
|
||||
<i class="fas fa-chevron-down installed-category-chevron"></i>
|
||||
</button>
|
||||
<div class="installed-category-filter" id="installedCategoryFilter" aria-hidden="true" style="display: none;">
|
||||
<div class="installed-filter-row">
|
||||
<span class="sort-label">{% trans "Show:" %}</span>
|
||||
<div class="filter-btns sort-btns">
|
||||
<button type="button" class="sort-btn filter-btn active" data-filter="all" id="installedFilterBtnAll" onclick="setInstalledFilter('all')" title="{% trans 'Show all plugins' %}">
|
||||
<i class="fas fa-th-list"></i> <span class="filter-btn-label">{% trans "All" %}</span>
|
||||
</button>
|
||||
<button type="button" class="sort-btn filter-btn" data-filter="installed" id="installedFilterBtnInstalled" onclick="setInstalledFilter('installed')" title="{% trans 'Show only installed plugins' %}">
|
||||
<i class="fas fa-check-circle"></i> <span class="filter-btn-label">{% trans "Installed only" %}</span>
|
||||
</button>
|
||||
<button type="button" class="sort-btn filter-btn" data-filter="active" id="installedFilterBtnActive" onclick="setInstalledFilter('active')" title="{% trans 'Show only active (enabled) plugins' %}">
|
||||
<i class="fas fa-power-off"></i> <span class="filter-btn-label">{% trans "Active only" %}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="installed-sort-row">
|
||||
<span class="sort-label">{% trans "Sort by:" %}</span>
|
||||
<div class="sort-btns">
|
||||
<button type="button" class="sort-btn active" data-sort-field="name" id="installedSortBtnName" onclick="toggleInstalledSort('name')" title="{% trans 'Click to toggle A-Å / Å-A' %}">
|
||||
<i class="fas fa-sort-alpha-down"></i> <span class="sort-btn-label">{% trans "Name A-Å" %}</span>
|
||||
</button>
|
||||
<button type="button" class="sort-btn" data-sort-field="type" id="installedSortBtnType" onclick="toggleInstalledSort('type')" title="{% trans 'By category/type' %}">
|
||||
<i class="fas fa-tag"></i> <span class="sort-btn-label">{% trans "Type" %}</span>
|
||||
</button>
|
||||
<button type="button" class="sort-btn" data-sort-field="date" id="installedSortBtnDate" onclick="toggleInstalledSort('date')" title="{% trans 'Click to toggle newest / oldest' %}">
|
||||
<i class="fas fa-calendar-alt"></i> <span class="sort-btn-label">{% trans "Date (newest)" %}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="installed-category-filter-btns">
|
||||
<button type="button" class="installed-category-btn active" data-category="all" onclick="filterByCategoryInstalled('all', event)">{% trans "All" %}</button>
|
||||
<button type="button" class="installed-category-btn" data-category="Utility" onclick="filterByCategoryInstalled('Utility', event)"><i class="fas fa-tools"></i> {% trans "Utility" %}</button>
|
||||
<button type="button" class="installed-category-btn" data-category="Security" onclick="filterByCategoryInstalled('Security', event)"><i class="fas fa-shield-alt"></i> {% trans "Security" %}</button>
|
||||
<button type="button" class="installed-category-btn" data-category="Backup" onclick="filterByCategoryInstalled('Backup', event)"><i class="fas fa-save"></i> {% trans "Backup" %}</button>
|
||||
<button type="button" class="installed-category-btn" data-category="Performance" onclick="filterByCategoryInstalled('Performance', event)"><i class="fas fa-rocket"></i> {% trans "Performance" %}</button>
|
||||
<button type="button" class="installed-category-btn" data-category="Monitoring" onclick="filterByCategoryInstalled('Monitoring', event)"><i class="fas fa-heartbeat"></i> {% trans "Monitoring" %}</button>
|
||||
<button type="button" class="installed-category-btn" data-category="Integration" onclick="filterByCategoryInstalled('Integration', event)"><i class="fas fa-plug"></i> {% trans "Integration" %}</button>
|
||||
<button type="button" class="installed-category-btn" data-category="Email" onclick="filterByCategoryInstalled('Email', event)"><i class="fas fa-envelope"></i> {% trans "Email" %}</button>
|
||||
<button type="button" class="installed-category-btn" data-category="Development" onclick="filterByCategoryInstalled('Development', event)"><i class="fas fa-code"></i> {% trans "Development" %}</button>
|
||||
<button type="button" class="installed-category-btn" data-category="Analytics" onclick="filterByCategoryInstalled('Analytics', event)"><i class="fas fa-chart-bar"></i> {% trans "Analytics" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1246,7 +1366,7 @@
|
||||
<!-- Grid View -->
|
||||
<div id="gridView" class="plugins-grid">
|
||||
{% for plugin in plugins %}
|
||||
<div class="plugin-card" data-plugin-name="{{ plugin.name }}" data-plugin-desc="{{ plugin.desc }}" data-plugin-type="{{ plugin.type }}" data-modify-date="{{ plugin.modify_date|default:'0000-00-00 00:00:00' }}">
|
||||
<div class="plugin-card" data-plugin-name="{{ plugin.name }}" data-plugin-desc="{{ plugin.desc }}" data-plugin-type="{{ plugin.type }}" data-modify-date="{{ plugin.modify_date|default:'0000-00-00 00:00:00' }}" data-installed="{{ plugin.installed|yesno:'true,false' }}" data-enabled="{{ plugin.enabled|yesno:'true,false' }}">
|
||||
<div class="plugin-header">
|
||||
<div class="plugin-icon">
|
||||
{% if plugin.type|lower == "security" %}
|
||||
@@ -1388,7 +1508,7 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for plugin in plugins %}
|
||||
<tr data-plugin-name="{{ plugin.name }}" data-plugin-desc="{{ plugin.desc }}" data-plugin-type="{{ plugin.type }}" data-modify-date="{{ plugin.modify_date|default:'0000-00-00 00:00:00' }}">
|
||||
<tr data-plugin-name="{{ plugin.name }}" data-plugin-desc="{{ plugin.desc }}" data-plugin-type="{{ plugin.type }}" data-modify-date="{{ plugin.modify_date|default:'0000-00-00 00:00:00' }}" data-installed="{{ plugin.installed|yesno:'true,false' }}" data-enabled="{{ plugin.enabled|yesno:'true,false' }}">
|
||||
<td>
|
||||
<strong>{{ plugin.name }}</strong>
|
||||
{% if plugin.freshness_badge %}
|
||||
@@ -1651,13 +1771,15 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Cache-busting version: 2026-02-01-v1 - Fixed category filter, added search bar, collapsible A-Å
|
||||
// Cache-busting version: 2026-02-15-v1 - Grid/Table: collapsible Category Filter (like A-Å in store)
|
||||
let storePlugins = [];
|
||||
let currentFilter = 'all';
|
||||
let currentCategory = 'all';
|
||||
let currentSearchQuery = '';
|
||||
let isSettingHash = false; // Flag to prevent infinite loops
|
||||
let currentInstalledSort = 'name-asc'; // name-asc, name-desc, type, date-desc, date-asc
|
||||
let currentInstalledFilter = 'all'; // all, installed, active
|
||||
let currentInstalledCategory = 'all'; // all, Utility, Security, ...
|
||||
|
||||
// Get CSRF cookie helper function
|
||||
function getCookie(name) {
|
||||
@@ -2035,14 +2157,43 @@ function clearPluginSearch() {
|
||||
}
|
||||
}
|
||||
|
||||
function setInstalledFilter(filter) {
|
||||
currentInstalledFilter = filter;
|
||||
var bar = document.getElementById('installedSortFilterBar');
|
||||
if (bar) {
|
||||
try {
|
||||
bar.querySelectorAll('.filter-btn').forEach(function(btn) {
|
||||
btn.classList.toggle('active', (btn.getAttribute('data-filter') || '') === filter);
|
||||
});
|
||||
} catch (e) { console.warn('setInstalledFilter: filter buttons', e); }
|
||||
}
|
||||
try {
|
||||
filterInstalledPlugins();
|
||||
} catch (e) { console.warn('setInstalledFilter: filterInstalledPlugins', e); }
|
||||
}
|
||||
|
||||
function filterInstalledPlugins() {
|
||||
const query = (document.getElementById('installedPluginSearchInput') && document.getElementById('installedPluginSearchInput').value) || '';
|
||||
const terms = query.trim().toLowerCase().split(/\s+/).filter(function(t) { return t.length > 0; });
|
||||
const filter = currentInstalledFilter || 'all';
|
||||
const gridView = document.getElementById('gridView');
|
||||
const tableView = document.getElementById('tableView');
|
||||
const noResultsGrid = document.getElementById('installedPluginsNoResultsGrid');
|
||||
const noResultsTable = document.getElementById('installedPluginsNoResultsTable');
|
||||
if (!gridView && !tableView) return;
|
||||
var visibleCount = 0;
|
||||
function matchesFilter(installed, enabled) {
|
||||
if (filter === 'all') return true;
|
||||
if (filter === 'installed') return installed === 'true';
|
||||
if (filter === 'active') return installed === 'true' && enabled === 'true';
|
||||
return true;
|
||||
}
|
||||
var cat = (typeof currentInstalledCategory !== 'undefined' ? currentInstalledCategory : 'all');
|
||||
function matchesCategory(typeAttr) {
|
||||
if (cat === 'all') return true;
|
||||
var t = (typeAttr || '').trim().toLowerCase();
|
||||
return t === (cat || '').trim().toLowerCase();
|
||||
}
|
||||
if (gridView) {
|
||||
var cards = gridView.querySelectorAll('.plugin-card');
|
||||
cards.forEach(function(card) {
|
||||
@@ -2050,7 +2201,12 @@ function filterInstalledPlugins() {
|
||||
var desc = (card.getAttribute('data-plugin-desc') || '').toLowerCase();
|
||||
var type = (card.getAttribute('data-plugin-type') || '').toLowerCase();
|
||||
var combined = name + ' ' + desc + ' ' + type;
|
||||
var show = terms.length === 0 || terms.every(function(term) { return combined.indexOf(term) !== -1; });
|
||||
var searchMatch = terms.length === 0 || terms.every(function(term) { return combined.indexOf(term) !== -1; });
|
||||
var installed = card.getAttribute('data-installed') || 'false';
|
||||
var enabled = card.getAttribute('data-enabled') || 'false';
|
||||
var filterMatch = matchesFilter(installed, enabled);
|
||||
var categoryMatch = matchesCategory(card.getAttribute('data-plugin-type'));
|
||||
var show = searchMatch && filterMatch && categoryMatch;
|
||||
card.style.display = show ? '' : 'none';
|
||||
if (show) visibleCount++;
|
||||
});
|
||||
@@ -2065,17 +2221,23 @@ function filterInstalledPlugins() {
|
||||
var desc = (row.getAttribute('data-plugin-desc') || '').toLowerCase();
|
||||
var type = (row.getAttribute('data-plugin-type') || '').toLowerCase();
|
||||
var combined = name + ' ' + desc + ' ' + type;
|
||||
var show = terms.length === 0 || terms.every(function(term) { return combined.indexOf(term) !== -1; });
|
||||
var searchMatch = terms.length === 0 || terms.every(function(term) { return combined.indexOf(term) !== -1; });
|
||||
var installed = row.getAttribute('data-installed') || 'false';
|
||||
var enabled = row.getAttribute('data-enabled') || 'false';
|
||||
var filterMatch = matchesFilter(installed, enabled);
|
||||
var categoryMatch = matchesCategory(row.getAttribute('data-plugin-type'));
|
||||
var show = searchMatch && filterMatch && categoryMatch;
|
||||
row.style.display = show ? '' : 'none';
|
||||
if (show) visibleCount++;
|
||||
});
|
||||
}
|
||||
}
|
||||
var hasFilterOrSearch = terms.length > 0 || (filter !== 'all') || (cat !== 'all');
|
||||
if (noResultsGrid) {
|
||||
noResultsGrid.style.display = (terms.length > 0 && visibleCount === 0) ? 'block' : 'none';
|
||||
noResultsGrid.style.display = (hasFilterOrSearch && visibleCount === 0) ? 'block' : 'none';
|
||||
}
|
||||
if (noResultsTable) {
|
||||
noResultsTable.style.display = (terms.length > 0 && visibleCount === 0) ? 'table-row' : 'none';
|
||||
noResultsTable.style.display = (hasFilterOrSearch && visibleCount === 0) ? 'table-row' : 'none';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2176,6 +2338,30 @@ function toggleAlphabetFilter() {
|
||||
toggleBtn.setAttribute('aria-expanded', isExpanded ? 'false' : 'true');
|
||||
}
|
||||
|
||||
function toggleInstalledCategoryFilter() {
|
||||
const filter = document.getElementById('installedCategoryFilter');
|
||||
const toggleBtn = document.getElementById('installedCategoryToggleBtn');
|
||||
if (!filter || !toggleBtn) return;
|
||||
const isExpanded = toggleBtn.getAttribute('aria-expanded') === 'true';
|
||||
filter.style.display = isExpanded ? 'none' : 'block';
|
||||
filter.setAttribute('aria-hidden', isExpanded ? 'true' : 'false');
|
||||
toggleBtn.setAttribute('aria-expanded', isExpanded ? 'false' : 'true');
|
||||
}
|
||||
|
||||
function filterByCategoryInstalled(category, evt) {
|
||||
currentInstalledCategory = category;
|
||||
const btns = document.querySelectorAll('.installed-category-btn');
|
||||
btns.forEach(function(btn) { btn.classList.remove('active'); });
|
||||
const clickedBtn = evt && (evt.currentTarget || (evt.target && evt.target.closest('.installed-category-btn')));
|
||||
if (clickedBtn) clickedBtn.classList.add('active');
|
||||
else {
|
||||
btns.forEach(function(btn) {
|
||||
if ((btn.getAttribute('data-category') || '') === category) btn.classList.add('active');
|
||||
});
|
||||
}
|
||||
try { filterInstalledPlugins(); } catch (e) { console.warn('filterByCategoryInstalled', e); }
|
||||
}
|
||||
|
||||
function upgradePlugin(pluginName, currentVersion, newVersion) {
|
||||
// Show confirmation dialog with backup warning
|
||||
const message = `⚠️ WARNING: Plugin Upgrade\n\n` +
|
||||
@@ -2386,43 +2572,54 @@ function installPlugin(pluginName) {
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Installing...';
|
||||
|
||||
fetch(`/plugins/api/install/${pluginName}/`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken'),
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
location.reload();
|
||||
} else {
|
||||
if (typeof PNotify !== 'undefined') {
|
||||
new PNotify({
|
||||
title: 'Installation Failed!',
|
||||
text: data.error || 'Failed to install plugin',
|
||||
type: 'error'
|
||||
});
|
||||
} else {
|
||||
alert('Error: ' + (data.error || 'Failed to install plugin'));
|
||||
}
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = originalText;
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
const headers = {
|
||||
'X-CSRFToken': getCookie('csrftoken'),
|
||||
'Content-Type': 'application/json'
|
||||
};
|
||||
|
||||
function showError(msg) {
|
||||
if (typeof PNotify !== 'undefined') {
|
||||
new PNotify({
|
||||
title: 'Error!',
|
||||
text: 'Failed to install plugin: ' + error.message,
|
||||
type: 'error'
|
||||
});
|
||||
new PNotify({ title: 'Installation Failed!', text: msg || 'Failed to install plugin', type: 'error' });
|
||||
} else {
|
||||
alert('Error: Failed to install plugin - ' + error.message);
|
||||
alert('Error: ' + (msg || 'Failed to install plugin'));
|
||||
}
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = originalText;
|
||||
}
|
||||
|
||||
function tryLocalInstall() {
|
||||
return fetch(`/plugins/api/install/${pluginName}/`, { method: 'POST', headers: headers })
|
||||
.then(function(r) { return r.json().then(function(data) { return { response: r, data: data }; }); });
|
||||
}
|
||||
|
||||
function tryStoreInstall() {
|
||||
return fetch(`/plugins/api/store/install/${pluginName}/`, { method: 'POST', headers: headers })
|
||||
.then(function(r) { return r.json().then(function(data) { return { response: r, data: data }; }); });
|
||||
}
|
||||
|
||||
tryLocalInstall()
|
||||
.then(function(result) {
|
||||
if (result.data.success) {
|
||||
location.reload();
|
||||
return;
|
||||
}
|
||||
var err = result.data.error || '';
|
||||
if (result.response.status === 404 || (err && err.indexOf('Plugin source not found') !== -1)) {
|
||||
btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Installing from store...';
|
||||
return tryStoreInstall();
|
||||
}
|
||||
showError(err);
|
||||
})
|
||||
.then(function(result) {
|
||||
if (!result || !result.data) return;
|
||||
if (result.data.success) {
|
||||
location.reload();
|
||||
} else {
|
||||
showError(result.data.error || 'Failed to install plugin');
|
||||
}
|
||||
})
|
||||
.catch(function(error) {
|
||||
showError(error && error.message ? error.message : 'Failed to install plugin');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2978,7 +3175,14 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
// Set initial view without updating hash (only update hash if there was already one)
|
||||
const hadHash = hash.length > 0;
|
||||
toggleView(initialView, hadHash);
|
||||
try {
|
||||
toggleView(initialView, hadHash);
|
||||
} catch (e) {
|
||||
console.warn('plugins: toggleView on load failed', e);
|
||||
if (storeView) storeView.style.display = 'block';
|
||||
if (gridView) gridView.style.display = 'none';
|
||||
if (tableView) tableView.style.display = 'none';
|
||||
}
|
||||
} else {
|
||||
// Elements don't exist (no plugins installed), just show store view directly
|
||||
if (storeView) {
|
||||
|
||||
@@ -13,10 +13,17 @@ from django.urls import path, include
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Ensure plugin roots are on sys.path first so __import__(plugin_name + '.urls') can find packages
|
||||
_INSTALLED_PLUGINS_PATH = '/usr/local/CyberCP'
|
||||
_PLUGIN_SOURCE_PATHS = ['/home/cyberpanel/plugins', '/home/cyberpanel-plugins']
|
||||
for _p in [_INSTALLED_PLUGINS_PATH] + _PLUGIN_SOURCE_PATHS:
|
||||
if _p and os.path.isdir(_p) and _p not in sys.path:
|
||||
sys.path.insert(0, _p)
|
||||
|
||||
from . import views
|
||||
|
||||
# Installed plugins live under this path (must match pluginInstaller and pluginHolder.views)
|
||||
INSTALLED_PLUGINS_PATH = '/usr/local/CyberCP'
|
||||
INSTALLED_PLUGINS_PATH = _INSTALLED_PLUGINS_PATH
|
||||
|
||||
# Source paths for plugins (same as pluginHolder.views PLUGIN_SOURCE_PATHS)
|
||||
# Checked when plugin is not under INSTALLED_PLUGINS_PATH so URLs still work
|
||||
@@ -95,29 +102,30 @@ urlpatterns = [
|
||||
path('api/store/upgrade/<str:plugin_name>/', views.upgrade_plugin, name='upgrade_plugin'),
|
||||
path('api/backups/<str:plugin_name>/', views.get_plugin_backups, name='get_plugin_backups'),
|
||||
path('api/revert/<str:plugin_name>/', views.revert_plugin, name='revert_plugin'),
|
||||
path('<str:plugin_name>/help/', views.plugin_help, name='plugin_help'),
|
||||
path('api/debug-plugins/', views.debug_loaded_plugins, name='debug_loaded_plugins'),
|
||||
]
|
||||
|
||||
# Dynamically include each installed plugin's URLs so /plugins/<plugin_name>/settings/ etc. work
|
||||
# Only include plugins that are in INSTALLED_APPS so Django can load their models.
|
||||
from django.conf import settings
|
||||
_installed_apps = getattr(settings, 'INSTALLED_APPS', ())
|
||||
|
||||
# Include each installed plugin's URLs *before* the catch-all so /plugins/<name>/settings/ etc. match
|
||||
_loaded_plugins = []
|
||||
_failed_plugins = {}
|
||||
for _plugin_name, _path_parent in _get_installed_plugin_list():
|
||||
if _plugin_name not in _installed_apps:
|
||||
continue
|
||||
try:
|
||||
# If plugin is from a source path, ensure it is on sys.path so import works
|
||||
if _path_parent not in sys.path:
|
||||
sys.path.insert(0, _path_parent)
|
||||
__import__(_plugin_name + '.urls')
|
||||
urlpatterns.append(path(_plugin_name + '/', include(_plugin_name + '.urls')))
|
||||
except (ImportError, AttributeError) as e:
|
||||
_loaded_plugins.append(_plugin_name)
|
||||
except Exception as e:
|
||||
import traceback
|
||||
_failed_plugins[_plugin_name] = str(e)
|
||||
try:
|
||||
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as _logging
|
||||
_logging.writeToFile(
|
||||
'pluginHolder.urls: Skipping plugin "%s" (urls not loadable): %s'
|
||||
% (_plugin_name, e)
|
||||
)
|
||||
_logging.writeToFile(traceback.format_exc())
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
urlpatterns.append(path('<str:plugin_name>/help/', views.plugin_help, name='plugin_help'))
|
||||
|
||||
@@ -5,6 +5,7 @@ from django.views.decorators.csrf import csrf_exempt
|
||||
from django.views.decorators.http import require_http_methods
|
||||
from plogical.mailUtilities import mailUtilities
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import shlex
|
||||
import json
|
||||
@@ -42,6 +43,17 @@ PLUGIN_SOURCE_PATHS = ['/home/cyberpanel/plugins', '/home/cyberpanel-plugins']
|
||||
# These plugins show "Built-in" badge and only Settings button (no Deactivate/Uninstall)
|
||||
BUILTIN_PLUGINS = frozenset(['emailMarketing', 'emailPremium'])
|
||||
|
||||
# Core CyberPanel app dirs under /usr/local/CyberCP that must not be counted as "installed plugins"
|
||||
# (matches pluginHolder.urls so Installed count = store/plugin dirs only, not core apps)
|
||||
RESERVED_PLUGIN_DIRS = frozenset([
|
||||
'api', 'backup', 'baseTemplate', 'cloudAPI', 'CLManager', 'containerization', 'CyberCP',
|
||||
'databases', 'dns', 'dockerManager', 'emailMarketing', 'emailPremium', 'filemanager',
|
||||
'firewall', 'ftp', 'highAvailability', 'IncBackups', 'loginSystem', 'mailServer',
|
||||
'managePHP', 'manageSSL', 'manageServices', 'packages', 'pluginHolder', 'plogical',
|
||||
'pluginInstaller', 'serverLogs', 'serverStatus', 's3Backups', 'tuning', 'userManagment',
|
||||
'websiteFunctions', 'aiScanner', 'dns', 'help', 'installed',
|
||||
])
|
||||
|
||||
def _get_plugin_source_path(plugin_name):
|
||||
"""Return the full path to a plugin's source directory, or None if not found."""
|
||||
for base in PLUGIN_SOURCE_PATHS:
|
||||
@@ -51,6 +63,30 @@ def _get_plugin_source_path(plugin_name):
|
||||
return path
|
||||
return None
|
||||
|
||||
def _ensure_plugin_meta_xml(plugin_name):
|
||||
"""
|
||||
If plugin is installed (directory exists) but meta.xml is missing,
|
||||
restore it from source or from GitHub so the grid and version checks work.
|
||||
"""
|
||||
installed_dir = os.path.join('/usr/local/CyberCP', plugin_name)
|
||||
installed_meta = os.path.join(installed_dir, 'meta.xml')
|
||||
if not os.path.isdir(installed_dir) or os.path.exists(installed_meta):
|
||||
return
|
||||
source_path = _get_plugin_source_path(plugin_name)
|
||||
if source_path:
|
||||
source_meta = os.path.join(source_path, 'meta.xml')
|
||||
if os.path.exists(source_meta):
|
||||
try:
|
||||
shutil.copy2(source_meta, installed_meta)
|
||||
logging.writeToFile(f"Restored meta.xml for {plugin_name} from source")
|
||||
except Exception as e:
|
||||
logging.writeToFile(f"Could not restore meta.xml for {plugin_name}: {e}")
|
||||
return
|
||||
try:
|
||||
_sync_meta_xml_from_github(plugin_name)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def _get_plugin_state_file(plugin_name):
|
||||
"""Get the path to the plugin state file"""
|
||||
if not os.path.exists(PLUGIN_STATE_DIR):
|
||||
@@ -121,6 +157,15 @@ def installed(request):
|
||||
errorPlugins = []
|
||||
processed_plugins = set() # Track which plugins we've already processed
|
||||
|
||||
# Repair pass: ensure every installed plugin dir has meta.xml (from source or GitHub) so counts and grid are correct
|
||||
if os.path.exists(installedPath):
|
||||
for plugin in os.listdir(installedPath):
|
||||
if plugin.startswith('.') or plugin in RESERVED_PLUGIN_DIRS:
|
||||
continue
|
||||
plugin_dir = os.path.join(installedPath, plugin)
|
||||
if os.path.isdir(plugin_dir):
|
||||
_ensure_plugin_meta_xml(plugin)
|
||||
|
||||
# First, process plugins from source directories (multiple paths: /home/cyberpanel/plugins, /home/cyberpanel-plugins)
|
||||
# BUT: Skip plugins that are already installed - we'll process those from the installed location instead
|
||||
for pluginPath in PLUGIN_SOURCE_PATHS:
|
||||
@@ -134,20 +179,20 @@ def installed(request):
|
||||
for plugin in os.listdir(pluginPath):
|
||||
if plugin in processed_plugins:
|
||||
continue
|
||||
# Skip if plugin is already installed - we'll process it from installed location instead
|
||||
completePath = installedPath + '/' + plugin + '/meta.xml'
|
||||
if os.path.exists(completePath):
|
||||
# Plugin is installed, skip source path - DON'T mark as processed yet
|
||||
# The installed location loop will handle it and mark it as processed
|
||||
continue
|
||||
# Skip files (like .zip files) - only process directories
|
||||
pluginDir = os.path.join(pluginPath, plugin)
|
||||
if not os.path.isdir(pluginDir):
|
||||
continue
|
||||
|
||||
# Use same "installed" criterion as install endpoint: plugin directory in /usr/local/CyberCP/
|
||||
installed_dir = os.path.join(installedPath, plugin)
|
||||
completePath = os.path.join(installedPath, plugin, 'meta.xml')
|
||||
if os.path.exists(completePath):
|
||||
# Plugin is fully installed (dir + meta.xml), skip - second loop will add it
|
||||
continue
|
||||
|
||||
data = {}
|
||||
# Try installed location first, then fallback to source location
|
||||
completePath = installedPath + '/' + plugin + '/meta.xml'
|
||||
sourcePath = os.path.join(pluginDir, 'meta.xml')
|
||||
|
||||
# Determine which meta.xml to use
|
||||
@@ -200,9 +245,9 @@ def installed(request):
|
||||
data['plugin_dir'] = plugin # Plugin directory name
|
||||
# Set builtin flag (core CyberPanel plugins vs user-installable plugins)
|
||||
data['builtin'] = plugin in BUILTIN_PLUGINS
|
||||
# Check if plugin is installed (only if it exists in /usr/local/CyberCP/)
|
||||
# Source directory presence doesn't mean installed - it just means the source files are available
|
||||
data['installed'] = os.path.exists(completePath)
|
||||
# Installed = plugin directory exists (must match install endpoint which uses directory existence)
|
||||
# Fixes grid showing "Not Installed" when directory exists but meta.xml is missing
|
||||
data['installed'] = os.path.isdir(installed_dir)
|
||||
|
||||
# Get plugin enabled state (only for installed plugins)
|
||||
if data['installed']:
|
||||
@@ -247,11 +292,9 @@ def installed(request):
|
||||
# Special handling for emailMarketing
|
||||
if plugin == 'emailMarketing':
|
||||
data['manage_url'] = '/emailMarketing/'
|
||||
elif os.path.exists(completePath):
|
||||
# Check if settings route exists, otherwise use main plugin URL
|
||||
settings_route = f'/plugins/{plugin}/settings/'
|
||||
elif data['installed']:
|
||||
# Plugin directory exists; use main plugin URL
|
||||
main_route = f'/plugins/{plugin}/'
|
||||
# Default to main route - most plugins have a main route even if no settings
|
||||
data['manage_url'] = main_route
|
||||
else:
|
||||
data['manage_url'] = None
|
||||
@@ -282,20 +325,14 @@ def installed(request):
|
||||
errorPlugins.append({'name': plugin, 'error': f'XML parse error: {str(e)}'})
|
||||
logging.writeToFile(f"Plugin {plugin}: XML parse error - {str(e)}")
|
||||
# Don't mark as processed if it failed - let installed check handle it
|
||||
# This ensures plugins that exist in /usr/local/CyberCP/ but have bad source meta.xml still get counted
|
||||
if not os.path.exists(completePath):
|
||||
# Only skip if it's not actually installed
|
||||
if not os.path.isdir(installed_dir):
|
||||
continue
|
||||
# If it exists in installed location, don't mark as processed so it gets checked there
|
||||
continue
|
||||
except Exception as e:
|
||||
errorPlugins.append({'name': plugin, 'error': f'Error loading plugin: {str(e)}'})
|
||||
logging.writeToFile(f"Plugin {plugin}: Error loading - {str(e)}")
|
||||
# Don't mark as processed if it failed - let installed check handle it
|
||||
if not os.path.exists(completePath):
|
||||
# Only skip if it's not actually installed
|
||||
if not os.path.isdir(installed_dir):
|
||||
continue
|
||||
# If it exists in installed location, don't mark as processed so it gets checked there
|
||||
continue
|
||||
|
||||
# Also check for installed plugins that don't have source directories
|
||||
@@ -311,6 +348,7 @@ def installed(request):
|
||||
if not os.path.isdir(pluginInstalledDir):
|
||||
continue
|
||||
|
||||
_ensure_plugin_meta_xml(plugin)
|
||||
metaXmlPath = os.path.join(pluginInstalledDir, 'meta.xml')
|
||||
if not os.path.exists(metaXmlPath):
|
||||
continue
|
||||
@@ -475,29 +513,30 @@ def installed(request):
|
||||
except Exception as e:
|
||||
logging.writeToFile(f"Plugin {plugin_name} fallback load error: {str(e)}")
|
||||
|
||||
# Calculate installed and active counts
|
||||
# Double-check by also counting plugins that actually exist in /usr/local/CyberCP/
|
||||
# Calculate installed and active counts: only count real plugins (have meta.xml, not core apps)
|
||||
installed_plugins_in_filesystem = set()
|
||||
if os.path.exists(installedPath):
|
||||
for plugin in os.listdir(installedPath):
|
||||
if plugin.startswith('.') or plugin in RESERVED_PLUGIN_DIRS:
|
||||
continue
|
||||
pluginInstalledDir = os.path.join(installedPath, plugin)
|
||||
if os.path.isdir(pluginInstalledDir):
|
||||
metaXmlPath = os.path.join(pluginInstalledDir, 'meta.xml')
|
||||
if os.path.exists(metaXmlPath):
|
||||
installed_plugins_in_filesystem.add(plugin)
|
||||
if not os.path.isdir(pluginInstalledDir):
|
||||
continue
|
||||
if not os.path.exists(os.path.join(pluginInstalledDir, 'meta.xml')):
|
||||
continue
|
||||
installed_plugins_in_filesystem.add(plugin)
|
||||
|
||||
# Count installed plugins from the list
|
||||
installed_count = len([p for p in pluginList if p.get('installed', False)])
|
||||
active_count = len([p for p in pluginList if p.get('installed', False) and p.get('enabled', False)])
|
||||
|
||||
# If there's a discrepancy, use the filesystem count as the source of truth
|
||||
# Use the larger of list count and filesystem count so header never shows less than grid
|
||||
filesystem_installed_count = len(installed_plugins_in_filesystem)
|
||||
if filesystem_installed_count != installed_count:
|
||||
logging.writeToFile(f"WARNING: Plugin count mismatch! List says {installed_count}, filesystem has {filesystem_installed_count}")
|
||||
logging.writeToFile(f"Plugins in filesystem: {sorted(installed_plugins_in_filesystem)}")
|
||||
logging.writeToFile(f"Plugins in list with installed=True: {[p.get('plugin_dir') for p in pluginList if p.get('installed', False)]}")
|
||||
# Use filesystem count as source of truth
|
||||
installed_count = filesystem_installed_count
|
||||
list_installed_count = len([p for p in pluginList if p.get('installed', False)])
|
||||
if filesystem_installed_count != list_installed_count:
|
||||
logging.writeToFile(f"Plugin count: list installed={list_installed_count}, filesystem with meta.xml={filesystem_installed_count}")
|
||||
installed_count = max(list_installed_count, filesystem_installed_count)
|
||||
if active_count > installed_count:
|
||||
active_count = installed_count
|
||||
|
||||
# Debug logging to help identify discrepancies
|
||||
logging.writeToFile(f"Plugin count: Total={len(pluginList)}, Installed={installed_count}, Active={active_count}")
|
||||
@@ -609,6 +648,7 @@ def install_plugin(request, plugin_name):
|
||||
# Set plugin to enabled by default after installation
|
||||
_set_plugin_state(plugin_name, True)
|
||||
|
||||
_ensure_plugin_meta_xml(plugin_name)
|
||||
logging.writeToFile(f"Plugin {plugin_name} installed successfully (upload)")
|
||||
return JsonResponse({
|
||||
'success': True,
|
||||
@@ -1783,6 +1823,7 @@ def install_from_store(request, plugin_name):
|
||||
# Set plugin to enabled by default after installation
|
||||
_set_plugin_state(plugin_name, True)
|
||||
|
||||
_ensure_plugin_meta_xml(plugin_name)
|
||||
return JsonResponse({
|
||||
'success': True,
|
||||
'message': f'Plugin {plugin_name} installed successfully from store'
|
||||
@@ -1813,6 +1854,24 @@ def install_from_store(request, plugin_name):
|
||||
'error': str(e)
|
||||
}, status=500)
|
||||
|
||||
@csrf_exempt
|
||||
@require_http_methods(["GET"])
|
||||
def debug_loaded_plugins(request):
|
||||
"""Return which plugins have URL routes loaded and which failed (for diagnosing 404s)."""
|
||||
try:
|
||||
import pluginHolder.urls as urls_mod
|
||||
loaded = list(getattr(urls_mod, '_loaded_plugins', []))
|
||||
failed = dict(getattr(urls_mod, '_failed_plugins', {}))
|
||||
return JsonResponse({
|
||||
'success': True,
|
||||
'loaded': loaded,
|
||||
'failed': failed,
|
||||
'loaded_count': len(loaded),
|
||||
'failed_count': len(failed),
|
||||
}, json_dumps_params={'indent': 2})
|
||||
except Exception as e:
|
||||
return JsonResponse({'success': False, 'error': str(e)}, status=500)
|
||||
|
||||
def plugin_help(request, plugin_name):
|
||||
"""Plugin-specific help page - shows plugin information, version history, and help content"""
|
||||
mailUtilities.checkHome()
|
||||
|
||||
@@ -24,7 +24,10 @@ fi
|
||||
echo "Upgrading CyberPanel from branch: $BRANCH_NAME"
|
||||
|
||||
rm -f /usr/local/cyberpanel_upgrade.sh
|
||||
wget -O /usr/local/cyberpanel_upgrade.sh https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/cyberpanel_upgrade.sh 2>/dev/null
|
||||
# Use same repo as this script (master3395); fallback to usmannasir for compatibility. Prefer curl with no-cache so --mariadb-version is respected.
|
||||
curl -sL -H 'Cache-Control: no-cache' -H 'Pragma: no-cache' -o /usr/local/cyberpanel_upgrade.sh "https://raw.githubusercontent.com/master3395/cyberpanel/$BRANCH_NAME/cyberpanel_upgrade.sh" 2>/dev/null || \
|
||||
wget -q -O /usr/local/cyberpanel_upgrade.sh "https://raw.githubusercontent.com/master3395/cyberpanel/$BRANCH_NAME/cyberpanel_upgrade.sh" 2>/dev/null || \
|
||||
wget -q -O /usr/local/cyberpanel_upgrade.sh "https://raw.githubusercontent.com/usmannasir/cyberpanel/$BRANCH_NAME/cyberpanel_upgrade.sh" 2>/dev/null
|
||||
chmod 700 /usr/local/cyberpanel_upgrade.sh
|
||||
# Pass -b so upgrade script skips branch prompt and uses our branch
|
||||
# Pass -b and all extra args (e.g. --mariadb-version 12.3, --backup-db, --no-backup-db) to upgrade script
|
||||
/usr/local/cyberpanel_upgrade.sh -b "$BRANCH_NAME" $EXTRA_ARGS
|
||||
|
||||
48
to-do/UPGRADE-MODULES-DESIGN.md
Normal file
48
to-do/UPGRADE-MODULES-DESIGN.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# CyberPanel Upgrade Script - Modular Layout for Debugging
|
||||
|
||||
## Goal
|
||||
|
||||
Split `cyberpanel_upgrade.sh` into modules under `upgrade_modules/` so each file is under 500 lines and easier to debug.
|
||||
|
||||
## Directory Layout
|
||||
|
||||
- `upgrade_modules/00_common.sh` - Debug_Log, Debug_Log2, Branch_Check, Check_Return, Regenerate_Cert, Retry_Command (DONE)
|
||||
- `upgrade_modules/01_variables.sh` - Set_Default_Variables (DONE)
|
||||
- `upgrade_modules/02_checks.sh` - Check_Root, Check_Server_IP, Check_OS, Check_Provider, Check_Argument
|
||||
- `upgrade_modules/03_mariadb.sh` - Pre_Upgrade_CentOS7_MySQL, Maybe_Backup_MariaDB_Before_Upgrade, Backup_MariaDB_Before_Upgrade, Migrate_MariaDB_To_UTF8
|
||||
- `upgrade_modules/04_git_url.sh` - Pre_Upgrade_Setup_Git_URL
|
||||
- `upgrade_modules/05_repository.sh` - Pre_Upgrade_Setup_Repository (~490 lines)
|
||||
- `upgrade_modules/06_components.sh` - Download_Requirement, Pre_Upgrade_Required_Components
|
||||
- `upgrade_modules/07_branch_input.sh` - Pre_Upgrade_Branch_Input
|
||||
- `upgrade_modules/08_main_upgrade.sh` - Main_Upgrade
|
||||
- `upgrade_modules/09_sync.sh` - Sync_CyberCP_To_Latest
|
||||
- `upgrade_modules/10_post_tweak.sh` - Post_Upgrade_System_Tweak
|
||||
- `upgrade_modules/11_display_final.sh` - Post_Install_Display_Final_Info, _br, _bl, _b
|
||||
|
||||
## Line Ranges in Current Script
|
||||
|
||||
- 00_common: 99-106, 237-263, 264-337
|
||||
- 01_variables: 27-98
|
||||
- 02_checks: 107-148, 149-206, 207-236, 352-399
|
||||
- 03_mariadb: 425-520
|
||||
- 04_git_url: 400-424
|
||||
- 05_repository: 521-1011
|
||||
- 06_components: 1012-1298
|
||||
- 07_branch_input: 1299-1311
|
||||
- 08_main_upgrade: 1312-1649
|
||||
- 09_sync: 1650-1688
|
||||
- 10_post_tweak: 1691-2023
|
||||
- 11_display_final: 2024-2118
|
||||
|
||||
## Main Script After Refactor
|
||||
|
||||
1. Root check, Sudo_Test
|
||||
2. If upgrade_modules/ exists: source each 00-11; else (one-liner) download modules from GitHub by branch and source
|
||||
3. Set_Default_Variables, Check_Root, Check_Server_IP, Check_OS, Check_Provider, Check_Argument
|
||||
4. Branch and MariaDB prompts
|
||||
5. Pre_Upgrade_Setup_Repository, Pre_Upgrade_Setup_Git_URL, Pre_Upgrade_Required_Components
|
||||
6. Main_Upgrade, Sync_CyberCP_To_Latest, Post_Upgrade_System_Tweak, Post_Install_Display_Final_Info
|
||||
|
||||
## Status
|
||||
|
||||
Done: 00_common.sh, 01_variables.sh. Remaining: create 02-11 and refactor main script to loader.
|
||||
104
upgrade_modules/00_common.sh
Normal file
104
upgrade_modules/00_common.sh
Normal file
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env bash
|
||||
# CyberPanel upgrade – common helpers (logging, check return, retry, branch check).
|
||||
# Sourced by cyberpanel_upgrade.sh. Do not run standalone.
|
||||
|
||||
Debug_Log() {
|
||||
echo -e "\n${1}=${2}\n" >> "/var/log/cyberpanel_debug_upgrade_$(date +"%Y-%m-%d")_${Random_Log_Name}.log"
|
||||
}
|
||||
|
||||
Debug_Log2() {
|
||||
echo -e "\n${1}" >> /var/log/upgradeLogs.txt
|
||||
}
|
||||
|
||||
Branch_Check() {
|
||||
if [[ "$1" = *.*.* ]]; then
|
||||
Output=$(awk -v num1="$Base_Number" -v num2="${1//[[:space:]]/}" '
|
||||
BEGIN {
|
||||
print "num1", (num1 < num2 ? "<" : ">="), "num2"
|
||||
}
|
||||
')
|
||||
if [[ $Output = *">="* ]]; then
|
||||
echo -e "\nYou must use version number higher than 2.3.4"
|
||||
exit
|
||||
else
|
||||
raw="${1//[[:space:]]/}"
|
||||
if [[ "$raw" = v* ]]; then
|
||||
Branch_Name="$raw"
|
||||
else
|
||||
Branch_Name="v$raw"
|
||||
fi
|
||||
echo -e "\nSet branch name to $Branch_Name...\n"
|
||||
fi
|
||||
else
|
||||
echo -e "\nPlease input a valid format version number."
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
Check_Return() {
|
||||
local LAST_EXIT_CODE=$?
|
||||
if [[ $LAST_EXIT_CODE != "0" ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] ERROR: Command failed with exit code: $LAST_EXIT_CODE" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
if [[ -n "$1" ]] ; then
|
||||
echo -e "\n\n\n$1"
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Error message: $1" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
echo -e "above command failed..."
|
||||
Debug_Log2 "command failed. For more information read /var/log/installLogs.txt [404]"
|
||||
if [[ "$2" = "no_exit" ]] || [[ "$3" = "continue" ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Continuing despite error..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
else
|
||||
if [[ "$1" == *"Virtualenv creation failed"* ]] || [[ "$1" == *"Python upgrade.py"* ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] FATAL: Critical error, exiting" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
exit $LAST_EXIT_CODE
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Non-critical error, continuing..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Command succeeded" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
}
|
||||
|
||||
Regenerate_Cert() {
|
||||
cat <<EOF >/usr/local/CyberCP/cert_conf
|
||||
[req]
|
||||
prompt=no
|
||||
distinguished_name=cyberpanel
|
||||
[cyberpanel]
|
||||
commonName = www.example.com
|
||||
countryName = CP
|
||||
localityName = CyberPanel
|
||||
organizationName = CyberPanel
|
||||
organizationalUnitName = CyberPanel
|
||||
stateOrProvinceName = CP
|
||||
emailAddress = mail@example.com
|
||||
name = CyberPanel
|
||||
surname = CyberPanel
|
||||
givenName = CyberPanel
|
||||
initials = CP
|
||||
dnQualifier = CyberPanel
|
||||
[server_exts]
|
||||
extendedKeyUsage = 1.3.6.1.5.5.7.3.1
|
||||
EOF
|
||||
if [[ $1 == "8090" ]]; then
|
||||
openssl req -x509 -config /usr/local/CyberCP/cert_conf -extensions 'server_exts' -nodes -days 820 -newkey rsa:2048 -keyout /usr/local/lscp/conf/key.pem -out /usr/local/lscp/conf/cert.pem
|
||||
fi
|
||||
if [[ $1 == "7080" ]]; then
|
||||
if [[ -f /usr/local/lsws/admin/conf/webadmin.key ]]; then
|
||||
key_path="/usr/local/lsws/admin/conf/webadmin.key"
|
||||
cert_path="/usr/local/lsws/admin/conf/webadmin.crt"
|
||||
else
|
||||
key_path="/usr/local/lsws/admin/conf/cert/admin.key"
|
||||
cert_path="/usr/local/lsws/admin/conf/cert/admin.crt"
|
||||
fi
|
||||
openssl req -x509 -config /usr/local/CyberCP/cert_conf -extensions 'server_exts' -nodes -days 820 -newkey rsa:2048 -keyout $key_path -out $cert_path
|
||||
fi
|
||||
rm -f /usr/local/CyberCP/cert_conf
|
||||
}
|
||||
|
||||
Retry_Command() {
|
||||
for i in {1..50}; do
|
||||
eval "$1" && break || echo -e "\n$1 has failed for $i times\nWait for 3 seconds and try again...\n"; sleep 3;
|
||||
done
|
||||
}
|
||||
61
upgrade_modules/01_variables.sh
Normal file
61
upgrade_modules/01_variables.sh
Normal file
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env bash
|
||||
# CyberPanel upgrade – set default variables and paths.
|
||||
# Sourced by cyberpanel_upgrade.sh.
|
||||
|
||||
Set_Default_Variables() {
|
||||
echo -e "Clearing old log files..."
|
||||
rm -f /var/log/cyberpanel_upgrade_debug.log
|
||||
rm -f /var/log/installLogs.txt
|
||||
rm -f /var/log/upgradeLogs.txt
|
||||
|
||||
echo -e "\n\n========================================" > /var/log/cyberpanel_upgrade_debug.log
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Starting CyberPanel Upgrade Script" >> /var/log/cyberpanel_upgrade_debug.log
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Old log files have been cleared" >> /var/log/cyberpanel_upgrade_debug.log
|
||||
echo -e "========================================\n" >> /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
rm -Rfv /usr/local/CyberCP/configservercsf 2>/dev/null || true
|
||||
rm -fv /home/cyberpanel/plugins/configservercsf 2>/dev/null || true
|
||||
rm -Rfv /usr/local/CyberCP/public/static/configservercsf 2>/dev/null || true
|
||||
sed -i "/configservercsf/d" /usr/local/CyberCP/CyberCP/settings.py 2>/dev/null || true
|
||||
sed -i "/configservercsf/d" /usr/local/CyberCP/CyberCP/urls.py 2>/dev/null || true
|
||||
if [ ! -e /etc/cxs/cxs.pl ]; then
|
||||
sed -i "/configserver/d" /usr/local/CyberCP/baseTemplate/templates/baseTemplate/index.html 2>/dev/null || true
|
||||
fi
|
||||
|
||||
export LC_CTYPE=en_US.UTF-8
|
||||
echo -e "\nFetching latest data from CyberPanel server...\n"
|
||||
echo -e "This may take few seconds..."
|
||||
|
||||
Server_Country="Unknown"
|
||||
Server_OS=""
|
||||
Server_OS_Version=""
|
||||
Server_Provider='Undefined'
|
||||
|
||||
Temp_Value=$(curl --silent --max-time 30 -4 https://cyberpanel.net/version.txt)
|
||||
Panel_Version=${Temp_Value:12:3}
|
||||
Panel_Build=${Temp_Value:25:1}
|
||||
|
||||
Branch_Name="v${Panel_Version}.${Panel_Build}"
|
||||
Base_Number="1.9.3"
|
||||
|
||||
Git_User=""
|
||||
Git_Content_URL=""
|
||||
Git_Clone_URL=""
|
||||
|
||||
MySQL_Version=$(mariadb -V 2>/dev/null | grep -P '\d+.\d+.\d+' -o || mysql -V 2>/dev/null | grep -P '\d+.\d+.\d+' -o)
|
||||
MySQL_Password=$(cat /etc/cyberpanel/mysqlPassword 2>/dev/null || echo "")
|
||||
|
||||
LSWS_Latest_URL="https://cyberpanel.sh/update.litespeedtech.com/ws/latest.php"
|
||||
LSWS_Tmp=$(curl --silent --max-time 30 -4 "$LSWS_Latest_URL" 2>/dev/null)
|
||||
LSWS_Stable_Line=$(echo "$LSWS_Tmp" | grep "LSWS_STABLE")
|
||||
LSWS_Stable_Version=$(expr "$LSWS_Stable_Line" : '.*LSWS_STABLE=\(.*\) BUILD .*')
|
||||
if [ -z "$LSWS_Stable_Version" ]; then
|
||||
LSWS_Stable_Version="6.3.4"
|
||||
fi
|
||||
|
||||
Debug_Log2 "Starting Upgrade...1"
|
||||
|
||||
rm -rf /root/cyberpanel_upgrade_tmp
|
||||
mkdir -p /root/cyberpanel_upgrade_tmp
|
||||
cd /root/cyberpanel_upgrade_tmp || exit
|
||||
}
|
||||
189
upgrade_modules/02_checks.sh
Normal file
189
upgrade_modules/02_checks.sh
Normal file
@@ -0,0 +1,189 @@
|
||||
#!/usr/bin/env bash
|
||||
# CyberPanel upgrade – root, server IP, OS, provider, and argument checks. Sourced by cyberpanel_upgrade.sh.
|
||||
|
||||
Check_Root() {
|
||||
echo -e "\nChecking root privileges..."
|
||||
# If we're actually root (uid 0), allow regardless of SUDO in environment (e.g. curl | sudo bash)
|
||||
if [[ $(id -u) -eq 0 ]] 2>/dev/null; then
|
||||
echo -e "\nYou are running as root...\n"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if echo "$Sudo_Test" | grep SUDO >/dev/null; then
|
||||
echo -e "\nYou are using SUDO, please run as root user...\n"
|
||||
echo -e "\nIf you don't have direct access to root user, please run \e[31msudo su -\e[39m command (do NOT miss the \e[31m-\e[39m at end or it will fail) and then run installation command again."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "\nYou must run as root user to install CyberPanel...\n"
|
||||
echo -e "Run: \e[31msudo su -\e[39m then run this script again, or: curl -sL <url> | sudo bash -s -- <args>"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Check_Server_IP() {
|
||||
echo -e "Checking server location...\n"
|
||||
|
||||
Server_Country=$(curl --silent --max-time 10 -4 https://cyberpanel.sh/?country)
|
||||
if [[ ${#Server_Country} != "2" ]] ; then
|
||||
Server_Country="Unknown"
|
||||
fi
|
||||
|
||||
if [[ "$Debug" = "On" ]] ; then
|
||||
Debug_Log "Server_Country" "$Server_Country"
|
||||
fi
|
||||
|
||||
if [[ "$*" = *"--mirror"* ]] ; then
|
||||
Server_Country="CN"
|
||||
echo -e "Forced to use mirror server due to --mirror argument...\n"
|
||||
fi
|
||||
|
||||
if [[ "$Server_Country" = *"CN"* ]] ; then
|
||||
Server_Country="CN"
|
||||
echo -e "Setting up to use mirror server...\n"
|
||||
fi
|
||||
}
|
||||
|
||||
Check_OS() {
|
||||
if [[ ! -f /etc/os-release ]] ; then
|
||||
echo -e "Unable to detect the Operating System...\n"
|
||||
exit
|
||||
fi
|
||||
|
||||
if ! uname -m | grep -qE 'x86_64|aarch64' ; then
|
||||
echo -e "x86_64 or ARM system is required...\n"
|
||||
exit
|
||||
fi
|
||||
|
||||
if grep -q -E "CentOS Linux 7|CentOS Linux 8|CentOS Linux 9|CentOS Stream 9" /etc/os-release ; then
|
||||
Server_OS="CentOS"
|
||||
elif grep -q "Red Hat Enterprise Linux" /etc/os-release ; then
|
||||
Server_OS="RedHat"
|
||||
elif grep -q -E "CloudLinux 7|CloudLinux 8|CloudLinux 9" /etc/os-release ; then
|
||||
Server_OS="CloudLinux"
|
||||
elif grep -q -E "Rocky Linux" /etc/os-release ; then
|
||||
Server_OS="RockyLinux"
|
||||
elif grep -q -E "AlmaLinux-8|AlmaLinux-9|AlmaLinux-10" /etc/os-release ; then
|
||||
Server_OS="AlmaLinux"
|
||||
# Set specific version for AlmaLinux 9+ to use dnf instead of yum
|
||||
if grep -q -E "AlmaLinux-9|AlmaLinux-10" /etc/os-release ; then
|
||||
Server_OS="AlmaLinux9"
|
||||
fi
|
||||
elif grep -q -E "Ubuntu 18.04|Ubuntu 20.04|Ubuntu 20.10|Ubuntu 22.04|Ubuntu 24.04|Ubuntu 24.04.3" /etc/os-release ; then
|
||||
Server_OS="Ubuntu"
|
||||
elif grep -q -E "Debian GNU/Linux 11|Debian GNU/Linux 12|Debian GNU/Linux 13" /etc/os-release ; then
|
||||
Server_OS="Ubuntu"
|
||||
elif grep -q -E "openEuler 20.03|openEuler 22.03" /etc/os-release ; then
|
||||
Server_OS="openEuler"
|
||||
else
|
||||
echo -e "Unable to detect your system..."
|
||||
echo -e "\nCyberPanel is supported on x86_64 based Ubuntu 18.04, Ubuntu 20.04, Ubuntu 20.10, Ubuntu 22.04, Ubuntu 24.04, Ubuntu 24.04.3, Debian 11, Debian 12, Debian 13, CentOS 7, CentOS 8, CentOS 9, CentOS Stream 9, AlmaLinux 8, AlmaLinux 9, AlmaLinux 10, RockyLinux 8, RockyLinux 9, RHEL 8, RHEL 9, CloudLinux 7, CloudLinux 8, CloudLinux 9, openEuler 20.03, openEuler 22.03...\n"
|
||||
Debug_Log2 "CyberPanel is supported on x86_64 based Ubuntu 18.04, Ubuntu 20.04, Ubuntu 20.10, Ubuntu 22.04, Ubuntu 24.04, Ubuntu 24.04.3, Debian 11, Debian 12, Debian 13, CentOS 7, CentOS 8, CentOS 9, CentOS Stream 9, AlmaLinux 8, AlmaLinux 9, AlmaLinux 10, RockyLinux 8, RockyLinux 9, RHEL 8, RHEL 9, CloudLinux 7, CloudLinux 8, CloudLinux 9, openEuler 20.03, openEuler 22.03... [404]"
|
||||
exit
|
||||
fi
|
||||
|
||||
Server_OS_Version=$(grep VERSION_ID /etc/os-release | awk -F[=,] '{print $2}' | tr -d \" | head -c2 | tr -d . )
|
||||
#to make 20.04 display as 20, etc.
|
||||
|
||||
echo -e "System: $Server_OS $Server_OS_Version detected...\n"
|
||||
|
||||
if [[ $Server_OS = "CloudLinux" ]] || [[ "$Server_OS" = "AlmaLinux" ]] || [[ "$Server_OS" = "RockyLinux" ]] || [[ "$Server_OS" = "RedHat" ]]; then
|
||||
# Keep AlmaLinux9 separate for dnf package management
|
||||
if [[ "$Server_OS" != "AlmaLinux9" ]]; then
|
||||
Server_OS="CentOS"
|
||||
#CloudLinux gives version id like 7.8, 7.9, so cut it to show first number only
|
||||
#treat CloudLinux, Rocky and Alma as CentOS
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$Debug" = "On" ]] ; then
|
||||
Debug_Log "Server_OS" "$Server_OS $Server_OS_Version"
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
Check_Provider() {
|
||||
if hash dmidecode >/dev/null 2>&1; then
|
||||
if [[ "$(dmidecode -s bios-vendor)" = "Google" ]]; then
|
||||
Server_Provider="Google Cloud Platform"
|
||||
elif [[ "$(dmidecode -s bios-vendor)" = "DigitalOcean" ]]; then
|
||||
Server_Provider="Digital Ocean"
|
||||
elif [[ "$(dmidecode -s system-product-name | cut -c 1-7)" = "Alibaba" ]]; then
|
||||
Server_Provider="Alibaba Cloud"
|
||||
elif [[ "$(dmidecode -s system-manufacturer)" = "Microsoft Corporation" ]]; then
|
||||
Server_Provider="Microsoft Azure"
|
||||
elif [[ -d /usr/local/qcloud ]]; then
|
||||
Server_Provider="Tencent Cloud"
|
||||
else
|
||||
Server_Provider="Undefined"
|
||||
fi
|
||||
else
|
||||
Server_Provider='Undefined'
|
||||
fi
|
||||
|
||||
if [[ -f /sys/devices/virtual/dmi/id/product_uuid ]]; then
|
||||
if [[ "$(cut -c 1-3 /sys/devices/virtual/dmi/id/product_uuid)" = 'EC2' ]] && [[ -d /home/ubuntu ]]; then
|
||||
Server_Provider='Amazon Web Service'
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$Debug" = "On" ]] ; then
|
||||
Debug_Log "Server_Provider" "$Server_Provider"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
Skip_System_Update=""
|
||||
# Migrate MariaDB from latin1 to utf8mb4 after upgrade (only when --migrate-to-utf8 and upgrading to 11.x/12.x)
|
||||
Migrate_MariaDB_To_UTF8_Requested=""
|
||||
# MariaDB version: any X.Y or X.Y.Z supported; highlighted: 10.11.16, 11.8 LTS, 12.x (default 11.8)
|
||||
MARIADB_VER="11.8"
|
||||
MARIADB_VER_REPO="11.8"
|
||||
|
||||
Check_Argument() {
|
||||
# Parse --branch / -b (extract first word after -b or --branch)
|
||||
if [[ "$*" = *"--branch "* ]]; then
|
||||
Branch_Name=$(echo "$*" | sed -n 's/.*--branch \([^ ]*\).*/\1/p' | head -1)
|
||||
[[ -n "$Branch_Name" ]] && Branch_Check "$Branch_Name"
|
||||
elif [[ "$*" = *"-b "* ]]; then
|
||||
Branch_Name=$(echo "$*" | sed -n 's/.*-b \([^ ]*\).*/\1/p' | head -1)
|
||||
[[ -n "$Branch_Name" ]] && Branch_Check "$Branch_Name"
|
||||
fi
|
||||
# Parse --repo / -r to use any GitHub user (same URL structure as usmannasir/cyberpanel)
|
||||
if [[ "$*" = *"--repo "* ]]; then
|
||||
Git_User_Override=$(echo "$*" | sed -n 's/.*--repo \([^ ]*\).*/\1/p' | head -1)
|
||||
fi
|
||||
if [[ "$*" = *"-r "* ]] && [[ -z "$Git_User_Override" ]]; then
|
||||
Git_User_Override=$(echo "$*" | sed -n 's/.*-r \([^ ]*\).*/\1/p' | head -1)
|
||||
fi
|
||||
# Parse --no-system-update to skip yum/dnf update -y (faster upgrade when system is already updated)
|
||||
if [[ "$*" = *"--no-system-update"* ]]; then
|
||||
Skip_System_Update="yes"
|
||||
echo -e "\nUsing --no-system-update: skipping full system package update.\n"
|
||||
fi
|
||||
# Parse --backup-db / --no-backup-db: pre-upgrade MariaDB backup. Default when neither set: ask user (may take a while).
|
||||
# --backup-db = always backup; --no-backup-db = never backup; omit both = prompt [y/N]
|
||||
Backup_DB_Before_Upgrade=""
|
||||
if [[ "$*" = *"--backup-db"* ]]; then
|
||||
Backup_DB_Before_Upgrade="yes"
|
||||
echo -e "\nUsing --backup-db: will create a full MariaDB backup before upgrade.\n"
|
||||
elif [[ "$*" = *"--no-backup-db"* ]]; then
|
||||
Backup_DB_Before_Upgrade="no"
|
||||
echo -e "\nUsing --no-backup-db: skipping MariaDB pre-upgrade backup.\n"
|
||||
fi
|
||||
# Parse --migrate-to-utf8: after upgrading to MariaDB 11.x/12.x, convert DBs/tables from latin1 to utf8mb4 (only if your apps support UTF-8)
|
||||
if [[ "$*" = *"--migrate-to-utf8"* ]]; then
|
||||
Migrate_MariaDB_To_UTF8_Requested="yes"
|
||||
echo -e "\nUsing --migrate-to-utf8: will convert databases to UTF-8 (utf8mb4) after MariaDB upgrade.\n"
|
||||
fi
|
||||
# Parse --mariadb-version (any version: 10.6, 10.11, 10.11.16, 11.8, 12.1, 12.2, 12.3, etc.). Default 11.8.
|
||||
# --mariadb is shorthand for --mariadb-version 10.11
|
||||
if [[ "$*" = *"--mariadb"* ]] && [[ "$*" != *"--mariadb-version "* ]]; then
|
||||
MARIADB_VER="10.11"
|
||||
echo -e "\nUsing --mariadb: MariaDB 10.11 selected (non-interactive).\n"
|
||||
elif [[ "$*" = *"--mariadb-version "* ]]; then
|
||||
MARIADB_VER=$(echo "$*" | sed -n 's/.*--mariadb-version \([^ ]*\).*/\1/p' | head -1)
|
||||
MARIADB_VER="${MARIADB_VER:-11.8}"
|
||||
fi
|
||||
# Allow any version; repo paths use major.minor (normalized later)
|
||||
}
|
||||
|
||||
88
upgrade_modules/03_mariadb.sh
Normal file
88
upgrade_modules/03_mariadb.sh
Normal file
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env bash
|
||||
# CyberPanel upgrade – MariaDB backup, optional UTF-8 migration, CentOS 7 MySQL upgrade.
|
||||
# Sourced by cyberpanel_upgrade.sh.
|
||||
|
||||
Pre_Upgrade_CentOS7_MySQL() {
|
||||
if [[ "$MySQL_Version" = "10.1" ]]; then
|
||||
cp /etc/my.cnf /etc/my.cnf.bak
|
||||
mkdir /etc/cnfbackup
|
||||
cp -R /etc/my.cnf.d/ /etc/cnfbackup/
|
||||
yum remove MariaDB-server MariaDB-client galera -y
|
||||
yum --enablerepo=mariadb -y install MariaDB-server MariaDB-client galera
|
||||
cp -f /etc/my.cnf.bak /etc/my.cnf
|
||||
rm -rf /etc/my.cnf.d/
|
||||
mv /etc/cnfbackup/my.cnf.d /etc/
|
||||
systemctl enable mariadb 2>/dev/null || systemctl enable mysql
|
||||
systemctl start mariadb 2>/dev/null || systemctl start mysql
|
||||
mariadb-upgrade -uroot -p"$MySQL_Password" 2>/dev/null || mysql_upgrade -uroot -p"$MySQL_Password"
|
||||
fi
|
||||
mariadb -uroot -p"$MySQL_Password" -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY '$MySQL_Password';flush privileges" 2>/dev/null || mysql -uroot -p"$MySQL_Password" -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY '$MySQL_Password';flush privileges"
|
||||
}
|
||||
|
||||
Maybe_Backup_MariaDB_Before_Upgrade() {
|
||||
if [[ "$Backup_DB_Before_Upgrade" = "no" ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] MariaDB pre-upgrade backup: skipped (--no-backup-db)." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
return 0
|
||||
fi
|
||||
if [[ "$Backup_DB_Before_Upgrade" = "" ]]; then
|
||||
echo -e "\nDo you want to backup all databases before MariaDB upgrade? (may take a while) [y/N]: "
|
||||
read -r -t 60 Tmp_Backup_Choice 2>/dev/null || Tmp_Backup_Choice=""
|
||||
if [[ "$Tmp_Backup_Choice" =~ ^[yY] ]] || [[ "$Tmp_Backup_Choice" =~ ^[yY][eE][sS] ]]; then
|
||||
Backup_DB_Before_Upgrade="yes"
|
||||
else
|
||||
Backup_DB_Before_Upgrade="no"
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] MariaDB pre-upgrade backup: skipped (user chose no or timeout)." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
Backup_MariaDB_Before_Upgrade
|
||||
}
|
||||
|
||||
Backup_MariaDB_Before_Upgrade() {
|
||||
local pass="" backup_dir="/root/cyberpanel_mariadb_backups" backup_file=""
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Starting MariaDB pre-upgrade backup... (this may take a few minutes)" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
[[ -f /etc/cyberpanel/mysqlPassword ]] || { echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] MariaDB pre-upgrade backup: skipped (no password file)." | tee -a /var/log/cyberpanel_upgrade_debug.log; return 0; }
|
||||
if grep -q '"mysqlpassword"' /etc/cyberpanel/mysqlPassword 2>/dev/null; then
|
||||
pass=$(python3 -c "import json; print(json.load(open('/etc/cyberpanel/mysqlPassword')).get('mysqlpassword',''))" 2>/dev/null)
|
||||
else
|
||||
pass=$(head -1 /etc/cyberpanel/mysqlPassword 2>/dev/null | tr -d '\r\n')
|
||||
fi
|
||||
[[ -z "$pass" ]] && echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] WARNING: Could not read MariaDB password, skipping pre-upgrade backup." | tee -a /var/log/cyberpanel_upgrade_debug.log && echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] MariaDB pre-upgrade backup: skipped." | tee -a /var/log/cyberpanel_upgrade_debug.log && return 0
|
||||
mkdir -p "$backup_dir"
|
||||
backup_file="${backup_dir}/mariadb_backup_before_upgrade_$(date +%Y%m%d_%H%M%S).sql.gz"
|
||||
if mariadb --skip-ssl -u root -p"$pass" -e "SELECT 1" 2>/dev/null | grep -q 1; then
|
||||
(mariadb-dump --skip-ssl -u root -p"$pass" --all-databases --single-transaction --routines --triggers --events 2>/dev/null || mysqldump --skip-ssl -u root -p"$pass" --all-databases --single-transaction --routines --triggers --events 2>/dev/null) | gzip > "$backup_file" 2>/dev/null
|
||||
if [[ -s "$backup_file" ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] MariaDB backup created: $backup_file" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] MariaDB pre-upgrade backup: done." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] WARNING: MariaDB backup file empty or failed." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] MariaDB pre-upgrade backup: skipped (dump failed)." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] WARNING: Could not connect to MariaDB for backup (skip-ssl). Skipping backup." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] MariaDB pre-upgrade backup: skipped (no connection)." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
}
|
||||
|
||||
Migrate_MariaDB_To_UTF8() {
|
||||
local pass="" dbs="" db="" t=""
|
||||
[[ -f /etc/cyberpanel/mysqlPassword ]] || return 0
|
||||
if grep -q '"mysqlpassword"' /etc/cyberpanel/mysqlPassword 2>/dev/null; then
|
||||
pass=$(python3 -c "import json; print(json.load(open('/etc/cyberpanel/mysqlPassword')).get('mysqlpassword',''))" 2>/dev/null)
|
||||
else
|
||||
pass=$(head -1 /etc/cyberpanel/mysqlPassword 2>/dev/null | tr -d '\r\n')
|
||||
fi
|
||||
[[ -z "$pass" ]] && return 0
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Migrating MariaDB to UTF-8 (utf8mb4)..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
mariadb --skip-ssl -u root -p"$pass" -e "SET GLOBAL character_set_server = 'utf8mb4'; SET GLOBAL collation_server = 'utf8mb4_unicode_ci';" 2>/dev/null || true
|
||||
dbs=$(mariadb --skip-ssl -u root -p"$pass" -sN -e "SHOW DATABASES;" 2>/dev/null) || true
|
||||
for db in $dbs; do
|
||||
[[ "$db" = "information_schema" ]] || [[ "$db" = "performance_schema" ]] || [[ "$db" = "sys" ]] || [[ "$db" = "mysql" ]] && continue
|
||||
mariadb --skip-ssl -u root -p"$pass" -e "ALTER DATABASE \`$db\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" 2>/dev/null || true
|
||||
for t in $(mariadb --skip-ssl -u root -p"$pass" -sN -e "SHOW TABLES FROM \`$db\`;" 2>/dev/null); do
|
||||
mariadb --skip-ssl -u root -p"$pass" "$db" -e "ALTER TABLE \`$t\` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" 2>/dev/null || true
|
||||
done
|
||||
done
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] MariaDB UTF-8 (utf8mb4) migration completed." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
}
|
||||
27
upgrade_modules/04_git_url.sh
Normal file
27
upgrade_modules/04_git_url.sh
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
# CyberPanel upgrade – set Git content and clone URLs (usmannasir or override).
|
||||
# Sourced by cyberpanel_upgrade.sh.
|
||||
|
||||
Pre_Upgrade_Setup_Git_URL() {
|
||||
if [[ $Server_Country != "CN" ]] ; then
|
||||
if [[ -n "$Git_User_Override" ]]; then
|
||||
Git_User="$Git_User_Override"
|
||||
echo -e "\nUsing GitHub repo: ${Git_User}/cyberpanel (same URL structure as usmannasir)\n"
|
||||
else
|
||||
Git_User="usmannasir"
|
||||
fi
|
||||
Git_Content_URL="https://raw.githubusercontent.com/${Git_User}/cyberpanel"
|
||||
Git_Clone_URL="https://github.com/${Git_User}/cyberpanel.git"
|
||||
else
|
||||
if [[ -n "$Git_User_Override" ]]; then
|
||||
Git_User="$Git_User_Override"
|
||||
else
|
||||
Git_User="qtwrk"
|
||||
fi
|
||||
Git_Content_URL="https://gitee.com/${Git_User}/cyberpanel/raw"
|
||||
Git_Clone_URL="https://gitee.com/${Git_User}/cyberpanel.git"
|
||||
fi
|
||||
if [[ "$Debug" = "On" ]] ; then
|
||||
Debug_Log "Git_URL" "$Git_Content_URL"
|
||||
fi
|
||||
}
|
||||
494
upgrade_modules/05_repository.sh
Normal file
494
upgrade_modules/05_repository.sh
Normal file
@@ -0,0 +1,494 @@
|
||||
#!/usr/bin/env bash
|
||||
# CyberPanel upgrade – repository setup (CentOS/AlmaLinux/Ubuntu/openEuler). Sourced by cyberpanel_upgrade.sh.
|
||||
|
||||
Pre_Upgrade_Setup_Repository() {
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Pre_Upgrade_Setup_Repository started for OS: $Server_OS" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
if [[ "$Server_OS" = "CentOS" ]] || [[ "$Server_OS" = "AlmaLinux9" ]] ; then
|
||||
# Reduce dnf/yum timeouts and mirror issues (e.g. ftp.lip6.fr connection timeout)
|
||||
for dnf_conf in /etc/dnf/dnf.conf /etc/yum.conf; do
|
||||
if [[ -f "$dnf_conf" ]]; then
|
||||
grep -q '^timeout=' "$dnf_conf" 2>/dev/null || echo 'timeout=120' >> "$dnf_conf"
|
||||
grep -q '^minrate=' "$dnf_conf" 2>/dev/null || echo 'minrate=1000' >> "$dnf_conf"
|
||||
grep -q '^retries=' "$dnf_conf" 2>/dev/null || echo 'retries=5' >> "$dnf_conf"
|
||||
break
|
||||
fi
|
||||
done
|
||||
# For AlmaLinux 9: switch to repo.almalinux.org baseurl to avoid "Cannot find valid baseurl for repo: appstream"
|
||||
if [[ "$Server_OS" = "AlmaLinux9" ]] && [[ -d /etc/yum.repos.d ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Fixing AlmaLinux 9 repos (appstream/baseos) for reliable mirror access" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
ALMA_VER="${Server_OS_Version:-9}"
|
||||
ARCH="x86_64"
|
||||
ALMA_BASE="https://repo.almalinux.org/almalinux/${ALMA_VER}"
|
||||
for repo in /etc/yum.repos.d/almalinux*.repo /etc/yum.repos.d/AlmaLinux*.repo; do
|
||||
[[ ! -f "$repo" ]] && continue
|
||||
if grep -q '^mirrorlist=' "$repo" 2>/dev/null; then
|
||||
sed -i 's|^mirrorlist=|#mirrorlist=|g' "$repo"
|
||||
sed -i 's|^#\s*baseurl=\(.*repo\.almalinux\.org.*\)|baseurl=\1|' "$repo"
|
||||
sed -i 's|^#baseurl=\(.*repo\.almalinux\.org.*\)|baseurl=\1|' "$repo"
|
||||
fi
|
||||
done
|
||||
# Ensure appstream/baseos have explicit baseurl; support [appstream], [almalinux-appstream], etc.
|
||||
for repofile in /etc/yum.repos.d/almalinux.repo /etc/yum.repos.d/almalinux*.repo /etc/yum.repos.d/AlmaLinux*.repo; do
|
||||
[[ ! -f "$repofile" ]] && continue
|
||||
for section in appstream almalinux-appstream AppStream; do
|
||||
if grep -q "^\[${section}\]" "$repofile" 2>/dev/null; then
|
||||
sed -i "/^\[${section}\]/,/^\[/ { s|^#\?baseurl=.*|baseurl=${ALMA_BASE}/AppStream/${ARCH}/os/|; s|^mirrorlist=.*|#mirrorlist=disabled| }" "$repofile"
|
||||
if ! sed -n "/^\[${section}\]/,/^\[/p" "$repofile" | grep -q '^baseurl='; then
|
||||
sed -i "/^\[${section}\]/a baseurl=${ALMA_BASE}/AppStream/${ARCH}/os/" "$repofile"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
for section in baseos almalinux-baseos BaseOS; do
|
||||
if grep -q "^\[${section}\]" "$repofile" 2>/dev/null; then
|
||||
sed -i "/^\[${section}\]/,/^\[/ { s|^#\?baseurl=.*|baseurl=${ALMA_BASE}/BaseOS/${ARCH}/os/|; s|^mirrorlist=.*|#mirrorlist=disabled| }" "$repofile"
|
||||
if ! sed -n "/^\[${section}\]/,/^\[/p" "$repofile" | grep -q '^baseurl='; then
|
||||
sed -i "/^\[${section}\]/a baseurl=${ALMA_BASE}/BaseOS/${ARCH}/os/" "$repofile"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
for section in crb extras; do
|
||||
if grep -q "^\[${section}\]" "$repofile" 2>/dev/null; then
|
||||
[[ "$section" = "crb" ]] && path="CRB" || path="extras"
|
||||
sed -i "/^\[${section}\]/,/^\[/ { s|^#\?baseurl=.*|baseurl=${ALMA_BASE}/${path}/${ARCH}/os/|; s|^mirrorlist=.*|#mirrorlist=disabled| }" "$repofile"
|
||||
if ! sed -n "/^\[${section}\]/,/^\[/p" "$repofile" | grep -q '^baseurl='; then
|
||||
sed -i "/^\[${section}\]/a baseurl=${ALMA_BASE}/${path}/${ARCH}/os/" "$repofile"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done
|
||||
# Fallback: create override with same repo IDs (loads last via zz- prefix, overrides broken config)
|
||||
if ! dnf makecache --quiet 2>/dev/null; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] dnf makecache failed, creating AlmaLinux repo override" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
cat > /etc/yum.repos.d/zz-almalinux-cyberpanel-fix.repo << EOF
|
||||
[baseos]
|
||||
name=AlmaLinux ${ALMA_VER} - BaseOS
|
||||
baseurl=${ALMA_BASE}/BaseOS/${ARCH}/os/
|
||||
enabled=1
|
||||
gpgcheck=1
|
||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-AlmaLinux-9
|
||||
|
||||
[appstream]
|
||||
name=AlmaLinux ${ALMA_VER} - AppStream
|
||||
baseurl=${ALMA_BASE}/AppStream/${ARCH}/os/
|
||||
enabled=1
|
||||
gpgcheck=1
|
||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-AlmaLinux-9
|
||||
|
||||
[extras]
|
||||
name=AlmaLinux ${ALMA_VER} - Extras
|
||||
baseurl=${ALMA_BASE}/extras/${ARCH}/os/
|
||||
enabled=1
|
||||
gpgcheck=1
|
||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-AlmaLinux-9
|
||||
|
||||
[crb]
|
||||
name=AlmaLinux ${ALMA_VER} - CRB
|
||||
baseurl=${ALMA_BASE}/CRB/${ARCH}/os/
|
||||
enabled=1
|
||||
gpgcheck=1
|
||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-AlmaLinux-9
|
||||
EOF
|
||||
dnf makecache --quiet 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Setting up repositories for $Server_OS..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
rm -f /etc/yum.repos.d/CyberPanel.repo
|
||||
rm -f /etc/yum.repos.d/litespeed.repo
|
||||
if [[ "$Server_Country" = "CN" ]] ; then
|
||||
curl -o /etc/yum.repos.d/litespeed.repo https://cyberpanel.sh/litespeed/litespeed_cn.repo
|
||||
else
|
||||
curl -o /etc/yum.repos.d/litespeed.repo https://cyberpanel.sh/litespeed/litespeed.repo
|
||||
fi
|
||||
yum clean all
|
||||
if [[ -z "$Skip_System_Update" ]]; then
|
||||
yum update -y
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M-%S")] Skipping yum update (--no-system-update)" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
yum autoremove epel-release -y
|
||||
rm -f /etc/yum.repos.d/epel.repo
|
||||
rm -f /etc/yum.repos.d/epel.repo.rpmsave
|
||||
yum autoremove epel-release -y
|
||||
#all pre-upgrade operation for CentOS both 7/8
|
||||
|
||||
if [[ "$Server_OS_Version" = "7" ]] ; then
|
||||
yum install epel-release -y
|
||||
yum -y install yum-utils
|
||||
yum -y groupinstall development
|
||||
rm -f /etc/yum.repos.d/dovecot.repo
|
||||
rm -f /etc/yum.repos.d/frank.repo
|
||||
rm -f /etc/yum.repos.d/ius-archive.repo
|
||||
rm -f /etc/yum.repos.d/ius.repo
|
||||
rm -f /etc/yum.repos.d/ius-testing.repo
|
||||
#rm -f /etc/yum.repos.d/lux.repo
|
||||
rm -f /etc/yum.repos.d/powerdns-auth-*
|
||||
|
||||
rm -f /etc/yum.repos.d/MariaDB.repo
|
||||
rm -f /etc/yum.repos.d/MariaDB.repo.rpmsave
|
||||
|
||||
yum erase gf-* -y
|
||||
|
||||
rm -f /etc/yum.repos.d/gf.repo
|
||||
rm -f /etc/yum.repos.d/gf.repo.rpmsave
|
||||
|
||||
rm -f /etc/yum.repos.d/copart-restic-epel-7.repo.repo
|
||||
rm -f /etc/yum.repos.d/copart-restic-epel-7.repo.rpmsave
|
||||
|
||||
rm -f /etc/yum.repos.d/ius-archive.repo
|
||||
rm -f /etc/yum.repos.d/ius.repo
|
||||
rm -f /etc/yum.repos.d/ius-testing.repo
|
||||
|
||||
yum clean all
|
||||
|
||||
curl -o /etc/yum.repos.d/powerdns-auth-43.repo https://cyberpanel.sh/repo.powerdns.com/repo-files/centos-auth-43.repo
|
||||
Check_Return "yum repo" "no_exit"
|
||||
|
||||
# Determine appropriate MariaDB repository based on OS version
|
||||
if [[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]] ; then
|
||||
MARIADB_REPO="rhel9-amd64"
|
||||
else
|
||||
MARIADB_REPO="centos7-amd64"
|
||||
fi
|
||||
|
||||
cat << EOF > /etc/yum.repos.d/MariaDB.repo
|
||||
# MariaDB $MARIADB_VER_REPO repository list - updated 2026-02
|
||||
# https://downloads.mariadb.org/mariadb/repositories/
|
||||
[mariadb]
|
||||
name = MariaDB $MARIADB_VER_REPO
|
||||
baseurl = https://mirror.mariadb.org/yum/$MARIADB_VER_REPO/$MARIADB_REPO
|
||||
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
|
||||
gpgcheck=1
|
||||
EOF
|
||||
|
||||
yum install yum-plugin-copr -y
|
||||
yum copr enable copart/restic -y
|
||||
rpm -ivh https://cyberpanel.sh/repo.ius.io/ius-release-el7.rpm
|
||||
|
||||
if [[ "$Server_Country" = "CN" ]] ; then
|
||||
sed -i 's|http://yum.mariadb.org|https://cyberpanel.sh/yum.mariadb.org|g' /etc/yum.repos.d/MariaDB.repo
|
||||
sed -i 's|https://yum.mariadb.org/RPM-GPG-KEY-MariaDB|https://cyberpanel.sh/yum.mariadb.org/RPM-GPG-KEY-MariaDB|g' /etc/yum.repos.d/MariaDB.repo
|
||||
# use MariaDB Mirror
|
||||
sed -i 's|https://download.copr.fedorainfracloud.org|https://cyberpanel.sh/download.copr.fedorainfracloud.org|g' /etc/yum.repos.d/_copr_copart-restic.repo
|
||||
sed -i 's|http://repo.iotti.biz|https://cyberpanel.sh/repo.iotti.biz|g' /etc/yum.repos.d/frank.repo
|
||||
sed -i "s|mirrorlist=https://mirrorlist.ghettoforge.net/el/7/gf/\$basearch/mirrorlist|baseurl=https://cyberpanel.sh/mirror.ghettoforge.net/distributions/gf/el/7/gf/x86_64/|g" /etc/yum.repos.d/gf.repo
|
||||
sed -i "s|mirrorlist=https://mirrorlist.ghettoforge.net/el/7/plus/\$basearch/mirrorlist|baseurl=https://cyberpanel.sh/mirror.ghettoforge.net/distributions/gf/el/7/plus/x86_64/|g" /etc/yum.repos.d/gf.repo
|
||||
sed -i 's|https://repo.ius.io|https://cyberpanel.sh/repo.ius.io|g' /etc/yum.repos.d/ius.repo
|
||||
sed -i 's|http://repo.iotti.biz|https://cyberpanel.sh/repo.iotti.biz|g' /etc/yum.repos.d/lux.repo
|
||||
sed -i 's|http://repo.powerdns.com|https://cyberpanel.sh/repo.powerdns.com|g' /etc/yum.repos.d/powerdns-auth-43.repo
|
||||
sed -i 's|https://repo.powerdns.com|https://cyberpanel.sh/repo.powerdns.com|g' /etc/yum.repos.d/powerdns-auth-43.repo
|
||||
fi
|
||||
yum install yum-plugin-priorities -y
|
||||
|
||||
yum update -y
|
||||
|
||||
yum install -y wget strace htop net-tools telnet curl which bc telnet htop libevent-devel gcc libattr-devel xz-devel gpgme-devel curl-devel git socat openssl-devel MariaDB-shared mariadb-devel python36u python36u-pip python36u-devel bind-utils
|
||||
|
||||
Pre_Upgrade_CentOS7_MySQL
|
||||
|
||||
#all pre-upgrade operation for CentOS 7
|
||||
elif [[ "$Server_OS_Version" = "8" ]] ; then
|
||||
# cat <<EOF >/etc/yum.repos.d/CentOS-PowerTools-CyberPanel.repo
|
||||
#[powertools-for-cyberpanel]
|
||||
#name=CentOS Linux \$releasever - PowerTools
|
||||
#mirrorlist=http://mirrorlist.centos.org/?release=\$releasever&arch=\$basearch&repo=PowerTools&infra=\$infra
|
||||
#baseurl=http://mirror.centos.org/\$contentdir/\$releasever/PowerTools/\$basearch/os/
|
||||
#gpgcheck=1
|
||||
#enabled=1
|
||||
#gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
|
||||
#EOF
|
||||
rm -f /etc/yum.repos.d/CentOS-PowerTools-CyberPanel.repo
|
||||
|
||||
if [[ "$Server_Country" = "CN" ]] ; then
|
||||
dnf --nogpg install -y https://cyberpanel.sh/mirror.ghettoforge.net/distributions/gf/gf-release-latest.gf.el8.noarch.rpm
|
||||
else
|
||||
dnf --nogpg install -y https://mirror.ghettoforge.net/distributions/gf/gf-release-latest.gf.el8.noarch.rpm
|
||||
fi
|
||||
|
||||
dnf install epel-release -y
|
||||
|
||||
dnf install -y wget strace htop net-tools telnet which bc telnet htop libevent-devel gcc libattr-devel xz-devel mariadb-connector-c-devel curl-devel git platform-python-devel tar socat bind-utils 2>/dev/null || dnf install -y --allowerasing wget strace htop net-tools telnet which bc htop libevent-devel gcc libattr-devel xz-devel mariadb-connector-c-devel curl-devel git platform-python-devel tar socat bind-utils
|
||||
dnf install gpgme-devel -y 2>/dev/null || true
|
||||
dnf install python3 -y
|
||||
|
||||
elif [[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]] ; then
|
||||
rm -f /etc/yum.repos.d/CentOS-PowerTools-CyberPanel.repo
|
||||
|
||||
if [[ "$Server_Country" = "CN" ]] ; then
|
||||
dnf --nogpg install -y https://cyberpanel.sh/mirror.ghettoforge.net/distributions/gf/gf-release-latest.gf.el9.noarch.rpm
|
||||
else
|
||||
dnf --nogpg install -y https://mirror.ghettoforge.net/distributions/gf/gf-release-latest.gf.el9.noarch.rpm
|
||||
fi
|
||||
|
||||
dnf install epel-release -y 2>/dev/null || {
|
||||
# Fallback when appstream was broken or epel-release not in repo (e.g. AlmaLinux 9)
|
||||
if [[ "$Server_OS_Version" = "9" ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Installing EPEL from Fedora RPM (epel-release not in repo)..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
# MariaDB repo for EL8/EL9: any version (repo path uses major.minor: 10.11, 11.8, 12.1, 12.2, 12.3, etc.)
|
||||
if [[ "$Server_OS_Version" = "8" ]] || [[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Configuring MariaDB $MARIADB_VER_REPO repository and upgrading MariaDB..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
Maybe_Backup_MariaDB_Before_Upgrade
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Writing MariaDB $MARIADB_VER_REPO repo and installing/upgrading packages..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
if [[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]]; then
|
||||
MARIADB_REPO="rhel9-amd64"
|
||||
else
|
||||
MARIADB_REPO="rhel8-amd64"
|
||||
fi
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Configuring MariaDB $MARIADB_VER_REPO repo for EL$Server_OS_Version (version $MARIADB_VER)..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
# Remove or backup any existing MariaDB repo that points to a different version, so dnf uses only our repo
|
||||
for f in /etc/yum.repos.d/mariadb.repo /etc/yum.repos.d/MariaDB.repo.rpmsave; do
|
||||
if [[ -f "$f" ]] && grep -q '10\.11\|10.6\|10.5' "$f" 2>/dev/null && [[ "$MARIADB_VER_REPO" != "10.11" ]]; then
|
||||
mv -f "$f" "${f}.bak.cyberpanel" 2>/dev/null && echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Backed up old repo $f to ${f}.bak.cyberpanel (was 10.x, we want $MARIADB_VER_REPO)" | tee -a /var/log/cyberpanel_upgrade_debug.log || true
|
||||
fi
|
||||
done
|
||||
cat << EOF > /etc/yum.repos.d/MariaDB.repo
|
||||
# MariaDB $MARIADB_VER_REPO repository - CyberPanel upgrade
|
||||
# https://downloads.mariadb.org/mariadb/repositories/
|
||||
[mariadb]
|
||||
name = MariaDB $MARIADB_VER_REPO
|
||||
baseurl = https://mirror.mariadb.org/yum/$MARIADB_VER_REPO/$MARIADB_REPO
|
||||
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
|
||||
gpgcheck=1
|
||||
EOF
|
||||
if [[ "$Server_Country" = "CN" ]]; then
|
||||
sed -i 's|http://yum.mariadb.org|https://cyberpanel.sh/yum.mariadb.org|g' /etc/yum.repos.d/MariaDB.repo
|
||||
sed -i 's|https://yum.mariadb.org/RPM-GPG-KEY-MariaDB|https://cyberpanel.sh/yum.mariadb.org/RPM-GPG-KEY-MariaDB|g' /etc/yum.repos.d/MariaDB.repo
|
||||
fi
|
||||
dnf clean metadata --disablerepo='*' --enablerepo=mariadb 2>/dev/null || true
|
||||
# MariaDB 10 -> 11 or 11 -> 12: RPM scriptlet blocks in-place upgrade; do manual stop, remove old server, install target, start, mariadb-upgrade
|
||||
MARIADB_OLD_10=$(rpm -qa 'MariaDB-server-10*' 2>/dev/null | head -1)
|
||||
MARIADB_OLD_11=$(rpm -qa 'MariaDB-server-11*' 2>/dev/null | head -1)
|
||||
# Also detect 11.x by package version (e.g. MariaDB-server-11.8.6-1.el9)
|
||||
[[ -z "$MARIADB_OLD_11" ]] && MARIADB_OLD_11=$(rpm -qa 'MariaDB-server*' 2>/dev/null | grep -E 'MariaDB-server-11\.' | head -1)
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] MariaDB detected: MARIADB_OLD_10=$MARIADB_OLD_10 MARIADB_OLD_11=$MARIADB_OLD_11 target=$MARIADB_VER_REPO" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
if [[ -n "$MARIADB_OLD_10" ]] && { [[ "$MARIADB_VER_REPO" =~ ^11\. ]] || [[ "$MARIADB_VER_REPO" =~ ^12\. ]]; }; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] MariaDB 10.x detected; performing manual upgrade to $MARIADB_VER_REPO (stop, remove, install, start, mariadb-upgrade)..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
systemctl stop mariadb 2>/dev/null || true
|
||||
sleep 2
|
||||
[[ -f /etc/my.cnf ]] && cp -a /etc/my.cnf /etc/my.cnf.bak.cyberpanel 2>/dev/null || true
|
||||
[[ -d /etc/my.cnf.d ]] && cp -a /etc/my.cnf.d /etc/my.cnf.d.bak.cyberpanel 2>/dev/null || true
|
||||
rpm -e "$MARIADB_OLD_10" --nodeps 2>/dev/null || true
|
||||
dnf install -y --enablerepo=mariadb MariaDB-server MariaDB-client MariaDB-devel 2>/dev/null || true
|
||||
mkdir -p /etc/my.cnf.d
|
||||
printf "[client]\nskip-ssl = true\n" > /etc/my.cnf.d/cyberpanel-client.cnf 2>/dev/null || true
|
||||
systemctl start mariadb 2>/dev/null || true
|
||||
sleep 2
|
||||
mariadb-upgrade -u root 2>/dev/null || true
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] MariaDB manual upgrade to $MARIADB_VER_REPO completed." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
elif [[ -n "$MARIADB_OLD_11" ]] && [[ "$MARIADB_VER_REPO" =~ ^12\. ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] MariaDB 11.x detected; performing manual upgrade to $MARIADB_VER_REPO (stop, remove, install, start, mariadb-upgrade)..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
systemctl stop mariadb 2>/dev/null || true
|
||||
sleep 2
|
||||
[[ -f /etc/my.cnf ]] && cp -a /etc/my.cnf /etc/my.cnf.bak.cyberpanel 2>/dev/null || true
|
||||
[[ -d /etc/my.cnf.d ]] && cp -a /etc/my.cnf.d /etc/my.cnf.d.bak.cyberpanel 2>/dev/null || true
|
||||
rpm -e "$MARIADB_OLD_11" --nodeps 2>/dev/null || true
|
||||
dnf install -y --enablerepo=mariadb MariaDB-server MariaDB-client MariaDB-devel 2>/dev/null || true
|
||||
mkdir -p /etc/my.cnf.d
|
||||
printf "[client]\nskip-ssl = true\n" > /etc/my.cnf.d/cyberpanel-client.cnf 2>/dev/null || true
|
||||
systemctl start mariadb 2>/dev/null || true
|
||||
sleep 2
|
||||
mariadb-upgrade -u root 2>/dev/null || true
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] MariaDB manual upgrade to $MARIADB_VER_REPO completed (11->12)." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
else
|
||||
# Normal install/upgrade (same version or 10.11)
|
||||
dnf install -y --enablerepo=mariadb MariaDB-server MariaDB-client MariaDB-devel 2>/dev/null || true
|
||||
dnf upgrade -y --enablerepo=mariadb MariaDB-server MariaDB-client MariaDB-devel 2>/dev/null || true
|
||||
systemctl restart mariadb 2>/dev/null || true
|
||||
# Fallback: if we wanted 12.x but server is still 11.x (RPM scriptlet blocked in-place upgrade), do manual 11->12
|
||||
if [[ "$MARIADB_VER_REPO" =~ ^12\. ]]; then
|
||||
STILL_11=$(rpm -qa 'MariaDB-server-11*' 2>/dev/null | head -1)
|
||||
[[ -z "$STILL_11" ]] && STILL_11=$(rpm -qa 'MariaDB-server*' 2>/dev/null | grep -E 'MariaDB-server-11\.' | head -1)
|
||||
if [[ -n "$STILL_11" ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] MariaDB server still 11.x after dnf upgrade; performing manual 11->12 upgrade..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
systemctl stop mariadb 2>/dev/null || true
|
||||
sleep 2
|
||||
[[ -f /etc/my.cnf ]] && cp -a /etc/my.cnf /etc/my.cnf.bak.cyberpanel 2>/dev/null || true
|
||||
[[ -d /etc/my.cnf.d ]] && cp -a /etc/my.cnf.d /etc/my.cnf.d.bak.cyberpanel 2>/dev/null || true
|
||||
rpm -e "$STILL_11" --nodeps 2>/dev/null || true
|
||||
dnf install -y --enablerepo=mariadb MariaDB-server MariaDB-client MariaDB-devel 2>/dev/null || true
|
||||
mkdir -p /etc/my.cnf.d
|
||||
printf "[client]\nskip-ssl = true\n" > /etc/my.cnf.d/cyberpanel-client.cnf 2>/dev/null || true
|
||||
systemctl start mariadb 2>/dev/null || true
|
||||
sleep 2
|
||||
mariadb-upgrade -u root 2>/dev/null || true
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] MariaDB manual 11->12 fallback completed." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
# Allow local client to connect without SSL (11.x client defaults to SSL; 10.x server may not have it)
|
||||
mkdir -p /etc/my.cnf.d
|
||||
printf "[client]\nskip-ssl = true\n" > /etc/my.cnf.d/cyberpanel-client.cnf 2>/dev/null || true
|
||||
# Optional: migrate from latin1 to UTF-8 (utf8mb4) when --migrate-to-utf8 and 11.x/12.x
|
||||
if [[ "$Migrate_MariaDB_To_UTF8_Requested" = "yes" ]] && { [[ "$MARIADB_VER_REPO" =~ ^11\. ]] || [[ "$MARIADB_VER_REPO" =~ ^12\. ]]; }; then
|
||||
Migrate_MariaDB_To_UTF8
|
||||
fi
|
||||
fi
|
||||
|
||||
# AlmaLinux 9 specific package installation
|
||||
if [[ "$Server_OS" = "AlmaLinux9" ]] ; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Installing AlmaLinux 9 specific packages (Development Tools, PHP deps, MariaDB)..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Install essential build tools
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Running: dnf groupinstall -y 'Development Tools' (may take a few minutes)..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
dnf groupinstall -y 'Development Tools'
|
||||
|
||||
# Install PHP dependencies that are missing on AlmaLinux 9
|
||||
dnf install -y ImageMagick ImageMagick-devel gd gd-devel libicu libicu-devel \
|
||||
oniguruma oniguruma-devel aspell aspell-devel libc-client libc-client-devel \
|
||||
libmemcached libmemcached-devel freetype-devel libjpeg-turbo-devel \
|
||||
libpng-devel libwebp-devel libXpm-devel libzip-devel openssl-devel \
|
||||
sqlite-devel libxml2-devel libxslt-devel curl-devel libedit-devel \
|
||||
readline-devel pkgconfig cmake gcc-c++
|
||||
|
||||
# Install/upgrade MariaDB from our repo (any version: 10.11, 11.8, 12.x). Manual path for 10->11 and 11->12.
|
||||
MARIADB_OLD_10_AL9=$(rpm -qa 'MariaDB-server-10*' 2>/dev/null | head -1)
|
||||
MARIADB_OLD_11_AL9=$(rpm -qa 'MariaDB-server-11*' 2>/dev/null | head -1)
|
||||
[[ -z "$MARIADB_OLD_11_AL9" ]] && MARIADB_OLD_11_AL9=$(rpm -qa 'MariaDB-server*' 2>/dev/null | grep -E 'MariaDB-server-11\.' | head -1)
|
||||
if [[ -n "$MARIADB_OLD_10_AL9" ]] && { [[ "$MARIADB_VER_REPO" =~ ^11\. ]] || [[ "$MARIADB_VER_REPO" =~ ^12\. ]]; }; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] MariaDB 10.x detected (AlmaLinux 9); manual upgrade to $MARIADB_VER_REPO..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
systemctl stop mariadb 2>/dev/null || true
|
||||
sleep 2
|
||||
[[ -f /etc/my.cnf ]] && cp -a /etc/my.cnf /etc/my.cnf.bak.cyberpanel 2>/dev/null || true
|
||||
[[ -d /etc/my.cnf.d ]] && cp -a /etc/my.cnf.d /etc/my.cnf.d.bak.cyberpanel 2>/dev/null || true
|
||||
rpm -e "$MARIADB_OLD_10_AL9" --nodeps 2>/dev/null || true
|
||||
dnf install -y --enablerepo=mariadb MariaDB-server MariaDB-devel 2>/dev/null || dnf install -y mariadb-server mariadb-devel
|
||||
mkdir -p /etc/my.cnf.d
|
||||
printf "[client]\nskip-ssl = true\n" > /etc/my.cnf.d/cyberpanel-client.cnf 2>/dev/null || true
|
||||
systemctl start mariadb 2>/dev/null || true
|
||||
sleep 2
|
||||
mariadb-upgrade -u root 2>/dev/null || true
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] MariaDB manual upgrade to $MARIADB_VER_REPO completed (AlmaLinux 9)." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
elif [[ -n "$MARIADB_OLD_11_AL9" ]] && [[ "$MARIADB_VER_REPO" =~ ^12\. ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] MariaDB 11.x detected (AlmaLinux 9); manual upgrade to $MARIADB_VER_REPO..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
systemctl stop mariadb 2>/dev/null || true
|
||||
sleep 2
|
||||
[[ -f /etc/my.cnf ]] && cp -a /etc/my.cnf /etc/my.cnf.bak.cyberpanel 2>/dev/null || true
|
||||
[[ -d /etc/my.cnf.d ]] && cp -a /etc/my.cnf.d /etc/my.cnf.d.bak.cyberpanel 2>/dev/null || true
|
||||
rpm -e "$MARIADB_OLD_11_AL9" --nodeps 2>/dev/null || true
|
||||
dnf install -y --enablerepo=mariadb MariaDB-server MariaDB-devel 2>/dev/null || dnf install -y mariadb-server mariadb-devel
|
||||
mkdir -p /etc/my.cnf.d
|
||||
printf "[client]\nskip-ssl = true\n" > /etc/my.cnf.d/cyberpanel-client.cnf 2>/dev/null || true
|
||||
systemctl start mariadb 2>/dev/null || true
|
||||
sleep 2
|
||||
mariadb-upgrade -u root 2>/dev/null || true
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] MariaDB manual upgrade to $MARIADB_VER_REPO completed (AlmaLinux 9, 11->12)." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
else
|
||||
dnf install -y --enablerepo=mariadb MariaDB-server MariaDB-devel 2>/dev/null || dnf install -y mariadb-server mariadb-devel
|
||||
dnf upgrade -y --enablerepo=mariadb MariaDB-server MariaDB-devel 2>/dev/null || true
|
||||
systemctl restart mariadb 2>/dev/null || true
|
||||
fi
|
||||
# Allow local client to connect without SSL
|
||||
mkdir -p /etc/my.cnf.d
|
||||
printf "[client]\nskip-ssl = true\n" > /etc/my.cnf.d/cyberpanel-client.cnf 2>/dev/null || true
|
||||
|
||||
# Install additional required packages (omit curl - AlmaLinux 9 has curl-minimal, avoid conflict)
|
||||
dnf install -y wget unzip zip rsync firewalld psmisc git python3 python3-pip python3-devel 2>/dev/null || dnf install -y --allowerasing wget unzip zip rsync firewalld psmisc git python3 python3-pip python3-devel
|
||||
fi
|
||||
|
||||
# Omit curl to avoid conflict with curl-minimal on AlmaLinux 9; curl-devel for build is separate
|
||||
dnf install -y wget strace htop net-tools telnet which bc telnet htop libevent-devel gcc libattr-devel xz-devel mariadb-connector-c-devel curl-devel git platform-python-devel tar socat bind-utils 2>/dev/null || dnf install -y --allowerasing wget strace htop net-tools telnet which bc htop libevent-devel gcc libattr-devel xz-devel mariadb-connector-c-devel curl-devel git platform-python-devel tar socat bind-utils
|
||||
dnf install gpgme-devel -y 2>/dev/null || true
|
||||
dnf install python3 -y
|
||||
fi
|
||||
elif [[ "$Server_OS" = "Ubuntu" ]] ; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Setting up Ubuntu repositories..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Ensure nobody group exists (required for various operations)
|
||||
if ! getent group nobody > /dev/null 2>&1 ; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Creating 'nobody' group..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
groupadd nobody
|
||||
fi
|
||||
|
||||
apt update -y
|
||||
if [[ -z "$Skip_System_Update" ]]; then
|
||||
export DEBIAN_FRONTEND=noninteractive ; apt-get -o Dpkg::Options::="--force-confold" upgrade -y
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Skipping apt upgrade (--no-system-update)" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
|
||||
# MariaDB: add official repo and install/upgrade to chosen version on Ubuntu/Debian (any version)
|
||||
if [[ -n "$MARIADB_VER_REPO" ]]; then
|
||||
Maybe_Backup_MariaDB_Before_Upgrade
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Configuring MariaDB $MARIADB_VER_REPO repo for Ubuntu/Debian (version $MARIADB_VER)..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
curl -LsS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | bash -s -- --mariadb-server-version="$MARIADB_VER_REPO" 2>/dev/null || true
|
||||
# Must run apt-get update after adding repo so 11.8 packages are visible (otherwise apt keeps 10.11)
|
||||
apt-get update -qq 2>/dev/null || apt-get update
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get install -y mariadb-server mariadb-client 2>/dev/null || true
|
||||
apt-get install -y -o Dpkg::Options::="--force-confold" mariadb-server mariadb-client 2>/dev/null || true
|
||||
systemctl restart mariadb 2>/dev/null || systemctl restart mysql 2>/dev/null || true
|
||||
if [[ "$Migrate_MariaDB_To_UTF8_Requested" = "yes" ]] && { [[ "$MARIADB_VER_REPO" =~ ^11\. ]] || [[ "$MARIADB_VER_REPO" =~ ^12\. ]]; }; then
|
||||
Migrate_MariaDB_To_UTF8
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$Server_OS_Version" = "22" ]] || [[ "$Server_OS_Version" = "24" ]] ; then
|
||||
if [[ "$Server_OS_Version" = "24" ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Installing Ubuntu 24.04 specific packages..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Installing Ubuntu 22.04 specific packages..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
# Install Python development packages required for virtualenv on Ubuntu 22.04/24.04
|
||||
DEBIAN_FRONTEND=noninteractive apt install -y python3-dev python3-venv python3-pip python3-setuptools python3-wheel
|
||||
DEBIAN_FRONTEND=noninteractive apt install -y dnsutils net-tools htop telnet libcurl4-gnutls-dev libgnutls28-dev libgcrypt20-dev libattr1 libattr1-dev liblzma-dev libgpgme-dev libcurl4-gnutls-dev libssl-dev nghttp2 libnghttp2-dev idn2 libidn2-dev libidn2-0-dev librtmp-dev libpsl-dev nettle-dev libgnutls28-dev libldap2-dev libgssapi-krb5-2 libk5crypto3 libkrb5-dev libcomerr2 libldap2-dev virtualenv git socat vim unzip zip libmariadb-dev-compat libmariadb-dev
|
||||
|
||||
else
|
||||
DEBIAN_FRONTEND=noninteractive apt install -y htop telnet libcurl4-gnutls-dev libgnutls28-dev libgcrypt20-dev libattr1 libattr1-dev liblzma-dev libgpgme-dev libmariadb-dev-compat libmariadb-dev libcurl4-gnutls-dev libssl-dev nghttp2 libnghttp2-dev idn2 libidn2-dev librtmp-dev libpsl-dev nettle-dev libgnutls28-dev libldap2-dev libgssapi-krb5-2 libk5crypto3 libkrb5-dev libcom-err2 libldap2-dev virtualenv git dnsutils
|
||||
fi
|
||||
DEBIAN_FRONTEND=noninteractive apt install -y python3-pip
|
||||
DEBIAN_FRONTEND=noninteractive apt install -y build-essential libssl-dev libffi-dev python3-dev
|
||||
DEBIAN_FRONTEND=noninteractive apt install -y python3-venv
|
||||
|
||||
### fix for pip issue on ubuntu 22 and 24
|
||||
|
||||
apt-get remove --purge virtualenv -y
|
||||
# Handle Ubuntu 24.04's externally-managed-environment policy
|
||||
if [[ "$Server_OS_Version" = "24" ]]; then
|
||||
echo -e "Ubuntu 24.04 detected - using apt for virtualenv installation"
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y python3-virtualenv
|
||||
else
|
||||
pip uninstall -y virtualenv 2>/dev/null || true
|
||||
rm -rf /usr/lib/python3/dist-packages/virtualenv*
|
||||
pip3 install --upgrade virtualenv
|
||||
fi
|
||||
|
||||
|
||||
if [[ "$Server_OS_Version" = "18" ]] ; then
|
||||
:
|
||||
#all pre-upgrade operation for Ubuntu 18
|
||||
elif [[ "$Server_OS_Version" = "20" ]] ; then
|
||||
# if ! grep -q "focal" /etc/apt/sources.list.d/dovecot.list ; then
|
||||
# sed -i 's|ce-2.3-latest/ubuntu/bionic bionic main|ce-2.3-latest/ubuntu/focal focal main|g' /etc/apt/sources.list.d/dovecot.list
|
||||
# rm -rf /etc/dovecot-backup
|
||||
# cp -r /etc/dovecot /etc/dovecot-backup
|
||||
# apt update
|
||||
# DEBIAN_FRONTEND=noninteractive apt -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" remove -y dovecot-mysql dovecot-pop3d dovecot-imapd
|
||||
# DEBIAN_FRONTEND=noninteractive apt -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install -y dovecot-mysql dovecot-pop3d dovecot-imapd
|
||||
# systemctl restart dovecot
|
||||
# fi
|
||||
#fix ubuntu 20 webmail login issue
|
||||
|
||||
rm -f /etc/apt/sources.list.d/dovecot.list
|
||||
apt update
|
||||
DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical apt -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" upgrade -y
|
||||
fi
|
||||
#all pre-upgrade operation for Ubuntu 20
|
||||
fi
|
||||
if [[ "$Server_OS" = "openEuler" ]] ; then
|
||||
rm -f /etc/yum.repos.d/CyberPanel.repo
|
||||
rm -f /etc/yum.repos.d/litespeed.repo
|
||||
|
||||
yum clean all
|
||||
yum update -y
|
||||
|
||||
dnf install -y wget strace htop net-tools telnet curl which bc telnet htop libevent-devel gcc libattr-devel xz-devel mariadb-devel curl-devel git python3-devel tar socat bind-utils
|
||||
dnf install gpgme-devel -y
|
||||
dnf install python3 -y
|
||||
fi
|
||||
#all pre-upgrade operation for openEuler
|
||||
}
|
||||
|
||||
290
upgrade_modules/06_components.sh
Normal file
290
upgrade_modules/06_components.sh
Normal file
@@ -0,0 +1,290 @@
|
||||
#!/usr/bin/env bash
|
||||
# CyberPanel upgrade – download requirements and required components (venv, pip, recovery). Sourced by cyberpanel_upgrade.sh.
|
||||
|
||||
Download_Requirement() {
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Starting Download_Requirement function..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
for i in {1..50};
|
||||
do
|
||||
if [[ "$Server_OS_Version" = "22" ]] || [[ "$Server_OS_Version" = "24" ]] || [[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Downloading requirements.txt for OS version $Server_OS_Version" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
if command -v wget >/dev/null 2>&1; then wget -O /usr/local/requirments.txt "${Git_Content_URL}/${Branch_Name}/requirments.txt" 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log; else curl -sL -o /usr/local/requirments.txt "${Git_Content_URL}/${Branch_Name}/requirments.txt" 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log; fi
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Downloading requirements-old.txt for OS version $Server_OS_Version" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
if command -v wget >/dev/null 2>&1; then wget -O /usr/local/requirments.txt "${Git_Content_URL}/${Branch_Name}/requirments-old.txt" 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log; else curl -sL -o /usr/local/requirments.txt "${Git_Content_URL}/${Branch_Name}/requirments-old.txt" 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log; fi
|
||||
fi
|
||||
if grep -q "Django==" /usr/local/requirments.txt ; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Requirements file downloaded successfully" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Fix pysftp dependency issue by removing it from requirements
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Fixing pysftp dependency issue..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
sed -i 's/^pysftp$/# pysftp - deprecated, using paramiko instead/' /usr/local/requirments.txt
|
||||
sed -i 's/pysftp/# pysftp - deprecated, using paramiko instead/' /usr/local/requirments.txt
|
||||
|
||||
break
|
||||
else
|
||||
echo -e "\n Requirement list has failed to download for $i times..."
|
||||
echo -e "Wait for 30 seconds and try again...\n"
|
||||
sleep 30
|
||||
fi
|
||||
done
|
||||
#special made function for Gitee.com, for whatever reason sometimes it fails to download this file
|
||||
}
|
||||
|
||||
|
||||
|
||||
Pre_Upgrade_Required_Components() {
|
||||
|
||||
# Check if CyberCP directory exists but is incomplete/damaged
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Checking CyberCP directory integrity..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Define essential CyberCP components
|
||||
CYBERCP_ESSENTIAL_DIRS=(
|
||||
"/usr/local/CyberCP/CyberCP"
|
||||
"/usr/local/CyberCP/plogical"
|
||||
"/usr/local/CyberCP/websiteFunctions"
|
||||
"/usr/local/CyberCP/manage"
|
||||
)
|
||||
|
||||
CYBERCP_MISSING=0
|
||||
for dir in "${CYBERCP_ESSENTIAL_DIRS[@]}"; do
|
||||
if [ ! -d "$dir" ]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] INFO: Essential directory missing (will restore): $dir" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
CYBERCP_MISSING=1
|
||||
fi
|
||||
done
|
||||
|
||||
# If essential directories are missing, perform automatic recovery (normal on some upgrade paths)
|
||||
if [ $CYBERCP_MISSING -eq 1 ]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] INFO: Restoring missing CyberCP directories from repository..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Backup any remaining configuration files if they exist
|
||||
if [ -f "/usr/local/CyberCP/CyberCP/settings.py" ]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Backing up existing settings.py..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
cp /usr/local/CyberCP/CyberCP/settings.py /tmp/cyberpanel_settings_backup.py
|
||||
fi
|
||||
|
||||
# Clone fresh CyberPanel repository
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Cloning fresh CyberPanel repository for recovery..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
cd /usr/local
|
||||
rm -rf CyberCP_recovery_tmp
|
||||
|
||||
if git clone "$Git_Clone_URL" CyberCP_recovery_tmp; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Repository cloned successfully for recovery" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Checkout the appropriate branch
|
||||
cd CyberCP_recovery_tmp
|
||||
git checkout "$Branch_Name" 2>/dev/null || git checkout stable
|
||||
|
||||
# Copy missing components while preserving existing configurations
|
||||
for dir in "${CYBERCP_ESSENTIAL_DIRS[@]}"; do
|
||||
if [ ! -d "$dir" ]; then
|
||||
# Extract relative path after /usr/local/CyberCP/
|
||||
relative_path=${dir#/usr/local/CyberCP/}
|
||||
if [ -d "/usr/local/CyberCP_recovery_tmp/$relative_path" ]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Restoring missing directory: $dir" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
mkdir -p "$(dirname "$dir")"
|
||||
cp -r "/usr/local/CyberCP_recovery_tmp/$relative_path" "$dir"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Restore settings.py if it was backed up
|
||||
if [ -f "/tmp/cyberpanel_settings_backup.py" ]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Restoring backed up settings.py..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
cp /tmp/cyberpanel_settings_backup.py /usr/local/CyberCP/CyberCP/settings.py
|
||||
fi
|
||||
|
||||
# Clean up temporary clone
|
||||
rm -rf /usr/local/CyberCP_recovery_tmp
|
||||
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Recovery completed. All essential CyberCP directories restored." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] ERROR: Failed to clone repository for recovery" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Please run full installation instead of upgrade" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd /root/cyberpanel_upgrade_tmp || cd /root
|
||||
fi
|
||||
|
||||
if [ "$Server_OS" = "Ubuntu" ]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Preparing Ubuntu environment for virtualenv..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
rm -rf /usr/local/CyberPanel
|
||||
|
||||
# For Ubuntu 22.04 and 24.04, handle virtualenv installation properly
|
||||
if [[ "$Server_OS_Version" = "22" ]] || [[ "$Server_OS_Version" = "24" ]]; then
|
||||
if [[ "$Server_OS_Version" = "24" ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Ubuntu 24.04: Using apt for virtualenv installation (externally-managed-environment policy)..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
# Ubuntu 24.04 has externally-managed-environment, use apt
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y python3-virtualenv python3-venv
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Ubuntu 22.04: Installing/upgrading virtualenv with proper dependencies..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
# Remove system virtualenv if it exists to avoid conflicts
|
||||
apt remove -y python3-virtualenv 2>/dev/null || true
|
||||
# Install latest virtualenv via pip
|
||||
pip3 install --upgrade pip setuptools wheel
|
||||
pip3 install --upgrade virtualenv
|
||||
fi
|
||||
else
|
||||
pip3 install --upgrade virtualenv
|
||||
fi
|
||||
else
|
||||
rm -rf /usr/local/CyberPanel
|
||||
# AlmaLinux 9/10, Rocky 9: use python3 -m venv (no virtualenv pkg needed)
|
||||
if [[ "$Server_OS" = "AlmaLinux" ]] || [[ "$Server_OS" = "AlmaLinux9" ]] || [[ "$Server_OS" = "RockyLinux" ]]; then
|
||||
if [[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] AlmaLinux/Rocky $Server_OS_Version: will use python3 -m venv, skipping virtualenv package" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
else
|
||||
if [ -e /usr/bin/pip3 ]; then PIP3="/usr/bin/pip3"; else PIP3="pip3.6"; fi
|
||||
$PIP3 install --default-timeout=3600 virtualenv
|
||||
Check_Return
|
||||
fi
|
||||
else
|
||||
if [ -e /usr/bin/pip3 ]; then PIP3="/usr/bin/pip3"; else PIP3="pip3.6"; fi
|
||||
$PIP3 install --default-timeout=3600 virtualenv
|
||||
Check_Return
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -f /usr/local/CyberPanel/bin/python2 ]]; then
|
||||
echo -e "\nPython 2 dectected, doing re-setup...\n"
|
||||
rm -rf /usr/local/CyberPanel/bin
|
||||
if [[ "$Server_OS" = "Ubuntu" ]] && ([[ "$Server_OS_Version" = "22" ]] || [[ "$Server_OS_Version" = "24" ]]); then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Ubuntu $Server_OS_Version detected, using python3 -m venv..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
python3 -m venv --system-site-packages /usr/local/CyberPanel
|
||||
elif [[ "$Server_OS" = "CentOS" ]] || [[ "$Server_OS" = "AlmaLinux" ]] || [[ "$Server_OS" = "AlmaLinux9" ]] || [[ "$Server_OS" = "RockyLinux" ]]; then
|
||||
if [[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] AlmaLinux/Rocky $Server_OS_Version detected, using python3 -m venv..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
python3 -m venv --system-site-packages /usr/local/CyberPanel
|
||||
else
|
||||
PYTHON_PATH=$(which python3 2>/dev/null || which python3.9 2>/dev/null || echo "/usr/bin/python3")
|
||||
virtualenv -p "$PYTHON_PATH" --system-site-packages /usr/local/CyberPanel
|
||||
fi
|
||||
else
|
||||
virtualenv -p /usr/bin/python3 --system-site-packages /usr/local/CyberPanel
|
||||
fi
|
||||
Check_Return
|
||||
elif [[ -d /usr/local/CyberPanel/bin/ ]]; then
|
||||
echo -e "\nNo need to re-setup virtualenv at /usr/local/CyberPanel...\n"
|
||||
else
|
||||
#!/bin/bash
|
||||
|
||||
echo -e "\nNo existing virtualenv found; creating fresh Python environment...\n"
|
||||
|
||||
# Attempt to create a virtual environment
|
||||
if [[ "$Server_OS" = "Ubuntu" ]] && ([[ "$Server_OS_Version" = "22" ]] || [[ "$Server_OS_Version" = "24" ]]); then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Ubuntu $Server_OS_Version detected, using python3 -m venv..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
python3 -m venv /usr/local/CyberPanel
|
||||
elif [[ "$Server_OS" = "CentOS" ]] || [[ "$Server_OS" = "AlmaLinux" ]] || [[ "$Server_OS" = "AlmaLinux9" ]] || [[ "$Server_OS" = "RockyLinux" ]]; then
|
||||
if [[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] AlmaLinux/Rocky $Server_OS_Version: using python3 -m venv (no virtualenv pkg needed)..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
python3 -m venv --system-site-packages /usr/local/CyberPanel
|
||||
else
|
||||
PYTHON_PATH=$(which python3 2>/dev/null || which python3.9 2>/dev/null || echo "/usr/bin/python3")
|
||||
virtualenv -p "$PYTHON_PATH" --system-site-packages /usr/local/CyberPanel
|
||||
fi
|
||||
else
|
||||
virtualenv -p /usr/bin/python3 --system-site-packages /usr/local/CyberPanel
|
||||
fi
|
||||
|
||||
# Check if the virtualenv/venv command failed
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "virtualenv command failed."
|
||||
|
||||
# Check if the operating system is AlmaLinux
|
||||
if grep -q "AlmaLinux" /etc/os-release; then
|
||||
echo "Operating system is AlmaLinux."
|
||||
|
||||
# Check if the 'packaging' module is installed via RPM
|
||||
if rpm -q python3-packaging >/dev/null 2>&1; then
|
||||
echo "'packaging' module installed via RPM. Proceeding with uninstallation."
|
||||
|
||||
# Uninstall the 'packaging' module using RPM
|
||||
sudo dnf remove python3-packaging -y
|
||||
|
||||
# Check if uninstallation was successful
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Successfully uninstalled 'packaging' module."
|
||||
|
||||
# Install and upgrade 'packaging' using pip
|
||||
pip install --upgrade packaging
|
||||
|
||||
# Verify the installation
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "'packaging' module reinstalled and upgraded successfully."
|
||||
if [[ "$Server_OS" = "Ubuntu" ]] && ([[ "$Server_OS_Version" = "22" ]] || [[ "$Server_OS_Version" = "24" ]]); then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Ubuntu: using python3 -m venv..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
python3 -m venv --system-site-packages /usr/local/CyberPanel
|
||||
elif [[ "$Server_OS" = "CentOS" ]] || [[ "$Server_OS" = "AlmaLinux" ]] || [[ "$Server_OS" = "AlmaLinux9" ]] || [[ "$Server_OS" = "RockyLinux" ]]; then
|
||||
if [[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]]; then
|
||||
python3 -m venv --system-site-packages /usr/local/CyberPanel
|
||||
else
|
||||
PYTHON_PATH=$(which python3 2>/dev/null || which python3.9 2>/dev/null || echo "/usr/bin/python3")
|
||||
virtualenv -p "$PYTHON_PATH" --system-site-packages /usr/local/CyberPanel
|
||||
fi
|
||||
else
|
||||
virtualenv -p /usr/bin/python3 --system-site-packages /usr/local/CyberPanel
|
||||
fi
|
||||
else
|
||||
echo "Failed to install 'packaging' module using pip."
|
||||
fi
|
||||
else
|
||||
echo "Failed to uninstall 'packaging' module using RPM."
|
||||
fi
|
||||
else
|
||||
echo "'packaging' module is not installed via RPM. No action taken."
|
||||
fi
|
||||
else
|
||||
echo "Operating system is not AlmaLinux. No action taken."
|
||||
fi
|
||||
else
|
||||
echo "virtualenv command executed successfully."
|
||||
fi
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
. /usr/local/CyberPanel/bin/activate
|
||||
pip install --upgrade pip setuptools packaging
|
||||
|
||||
Download_Requirement
|
||||
|
||||
if [[ "$Server_OS" = "CentOS" ]] ; then
|
||||
# $PIP3 install --default-timeout=3600 virtualenv==16.7.9
|
||||
# Check_Return
|
||||
$PIP3 install --default-timeout=3600 --ignore-installed -r /usr/local/requirments.txt
|
||||
Check_Return
|
||||
elif [[ "$Server_OS" = "Ubuntu" ]] ; then
|
||||
# shellcheck disable=SC1091
|
||||
. /usr/local/CyberPanel/bin/activate
|
||||
Check_Return
|
||||
# pip3 install --default-timeout=3600 virtualenv==16.7.9
|
||||
# Check_Return
|
||||
pip3 install --default-timeout=3600 --ignore-installed -r /usr/local/requirments.txt
|
||||
Check_Return
|
||||
elif [[ "$Server_OS" = "openEuler" ]] ; then
|
||||
# pip3 install --default-timeout=3600 virtualenv==16.7.9
|
||||
# Check_Return
|
||||
pip3 install --default-timeout=3600 --ignore-installed -r /usr/local/requirments.txt
|
||||
Check_Return
|
||||
fi
|
||||
|
||||
#virtualenv -p /usr/bin/python3 --system-site-packages /usr/local/CyberPanel
|
||||
# Check_Return
|
||||
|
||||
wget "${Git_Content_URL}/${Branch_Name}/plogical/upgrade.py"
|
||||
|
||||
if [[ "$Server_Country" = "CN" ]] ; then
|
||||
sed -i 's|git clone https://github.com/usmannasir/cyberpanel|echo git cloned|g' upgrade.py
|
||||
|
||||
Retry_Command "git clone ${Git_Clone_URL}"
|
||||
Check_Return "git clone ${Git_Clone_URL}"
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
sed -i 's|https://raw.githubusercontent.com/usmannasir/cyberpanel/stable/install/litespeed/httpd_config.xml|'${Git_Content_URL}/${Branch_Name}'//install/litespeed/httpd_config.xml|g' upgrade.py
|
||||
sed -i 's|https://cyberpanel.sh/composer.sh|https://gitee.com/qtwrk/cyberpanel/raw/stable/install/composer_cn.sh|g' upgrade.py
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
# (Pre_Upgrade_Setup_Git_URL is defined earlier; this duplicate removed so --repo is respected)
|
||||
|
||||
16
upgrade_modules/07_branch_input.sh
Normal file
16
upgrade_modules/07_branch_input.sh
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
# CyberPanel upgrade – branch input prompt. Sourced by cyberpanel_upgrade.sh.
|
||||
|
||||
Pre_Upgrade_Branch_Input() {
|
||||
echo -e "\nPress the Enter key to continue with latest version, or enter specific version such as: \e[31m2.3.4\e[39m , \e[31m2.4.4\e[39m ...etc"
|
||||
echo -e "\nIf nothing is input in 10 seconds, script will proceed with the latest stable version. "
|
||||
echo -e "\nPlease press the Enter key or specify a version number, or wait for 10 seconds: "
|
||||
printf "%s" ""
|
||||
read -r -t 10 Tmp_Input
|
||||
if [[ $Tmp_Input = "" ]]; then
|
||||
echo -e "Branch name set to $Branch_Name"
|
||||
else
|
||||
Branch_Check "$Tmp_Input"
|
||||
fi
|
||||
}
|
||||
|
||||
341
upgrade_modules/08_main_upgrade.sh
Normal file
341
upgrade_modules/08_main_upgrade.sh
Normal file
@@ -0,0 +1,341 @@
|
||||
#!/usr/bin/env bash
|
||||
# CyberPanel upgrade – main upgrade (Python, upgrade.py, venv, WSGI). Sourced by cyberpanel_upgrade.sh.
|
||||
|
||||
Main_Upgrade() {
|
||||
echo -e "\n[$(date +"%Y-%m-%d %H:%M:%S")] Starting Main_Upgrade function..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Resolve Python for upgrade (avoid FileNotFoundError when /usr/local/CyberPanel/bin/python missing)
|
||||
CP_PYTHON=""
|
||||
for py in /usr/local/CyberPanel/bin/python /usr/local/CyberCP/bin/python /usr/bin/python3 /usr/local/bin/python3; do
|
||||
if [[ -x "$py" ]]; then CP_PYTHON="$py"; break; fi
|
||||
done
|
||||
if [[ -z "$CP_PYTHON" ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] ERROR: No Python found for upgrade (tried CyberPanel, CyberCP, python3)" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
exit 1
|
||||
fi
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Using Python: $CP_PYTHON" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Ensure ols_binaries_config exists (required by upgrade.py; may be missing when upgrading from older versions)
|
||||
mkdir -p /usr/local/CyberCP/install
|
||||
if [[ ! -f /usr/local/CyberCP/install/ols_binaries_config.py ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Downloading ols_binaries_config.py (required for upgrade)..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
wget -q -O /usr/local/CyberCP/install/ols_binaries_config.py "${Git_Content_URL}/${Branch_Name}/install/ols_binaries_config.py" 2>/dev/null || \
|
||||
curl -sL -o /usr/local/CyberCP/install/ols_binaries_config.py "${Git_Content_URL}/${Branch_Name}/install/ols_binaries_config.py" 2>/dev/null || true
|
||||
fi
|
||||
if [[ ! -f /usr/local/CyberCP/install/ols_binaries_config.py ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] WARNING: ols_binaries_config.py not found; upgrade.py may fail with ModuleNotFoundError" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Running: $CP_PYTHON upgrade.py $Branch_Name" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Run upgrade.py and capture output
|
||||
upgrade_output=$("$CP_PYTHON" upgrade.py "$Branch_Name" 2>&1)
|
||||
RETURN_CODE=$?
|
||||
echo "$upgrade_output" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Check for TypeError specifically
|
||||
if echo "$upgrade_output" | grep -q "TypeError: expected string or bytes-like object"; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] WARNING: TypeError detected in upgrade.py, but continuing..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
# Check if upgrade actually completed despite the error
|
||||
if echo "$upgrade_output" | grep -q "Upgrade Completed"; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Upgrade completed despite TypeError" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
RETURN_CODE=0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Python upgrade.py returned code: $RETURN_CODE" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Check if the command was successful (return code 0)
|
||||
if [ $RETURN_CODE -eq 0 ]; then
|
||||
echo "Upgrade successful."
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] First upgrade attempt successful" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] First upgrade attempt failed with code $RETURN_CODE, starting fallback..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
|
||||
if [ -e /usr/bin/pip3 ]; then
|
||||
PIP3="/usr/bin/pip3"
|
||||
else
|
||||
PIP3="pip3.6"
|
||||
fi
|
||||
|
||||
rm -rf /usr/local/CyberPanelTemp
|
||||
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Creating temporary virtual environment for fallback upgrade..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Try python3 -m venv first (more reliable on Ubuntu 22.04)
|
||||
if python3 -m venv --system-site-packages /usr/local/CyberPanelTemp 2>/dev/null; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Temporary virtualenv created with python3 -m venv" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
else
|
||||
# Fallback to virtualenv command
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Trying virtualenv command for temporary environment..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
virtualenv -p /usr/bin/python3 --system-site-packages /usr/local/CyberPanelTemp 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
. /usr/local/CyberPanelTemp/bin/activate
|
||||
|
||||
wget -O /usr/local/requirments-old.txt "${Git_Content_URL}/${Branch_Name}/requirments-old.txt"
|
||||
|
||||
if [[ "$Server_OS" = "CentOS" ]] ; then
|
||||
# $PIP3 install --default-timeout=3600 virtualenv==16.7.9
|
||||
# Check_Return
|
||||
$PIP3 install --default-timeout=3600 --ignore-installed -r /usr/local/requirments-old.txt
|
||||
Check_Return
|
||||
elif [[ "$Server_OS" = "Ubuntu" ]] ; then
|
||||
# shellcheck disable=SC1091
|
||||
. /usr/local/CyberPanelTemp/bin/activate
|
||||
Check_Return
|
||||
pip3 install --default-timeout=3600 --ignore-installed -r /usr/local/requirments-old.txt
|
||||
Check_Return
|
||||
elif [[ "$Server_OS" = "openEuler" ]] ; then
|
||||
pip3 install --default-timeout=3600 --ignore-installed -r /usr/local/requirments-old.txt
|
||||
Check_Return
|
||||
fi
|
||||
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Running fallback: /usr/local/CyberPanelTemp/bin/python upgrade.py $Branch_Name" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
/usr/local/CyberPanelTemp/bin/python upgrade.py "$Branch_Name" 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
FALLBACK_CODE=$?
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Fallback upgrade returned code: $FALLBACK_CODE" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
Check_Return
|
||||
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Removing temporary environment..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
rm -rf /usr/local/CyberPanelTemp
|
||||
|
||||
fi
|
||||
|
||||
echo -e "\n[$(date +"%Y-%m-%d %H:%M:%S")] Starting post-upgrade cleanup..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Check if we need to recreate due to Python 2
|
||||
NEEDS_RECREATE=0
|
||||
if [[ -f /usr/local/CyberCP/bin/python2 ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Found Python 2 in CyberCP, will recreate with Python 3..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
NEEDS_RECREATE=1
|
||||
fi
|
||||
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Removing old CyberCP virtual environment directories..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
rm -rf /usr/local/CyberCP/bin
|
||||
rm -rf /usr/local/CyberCP/lib
|
||||
rm -rf /usr/local/CyberCP/lib64
|
||||
rm -rf /usr/local/CyberCP/pyvenv.cfg
|
||||
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Checking CyberCP virtual environment status after cleanup..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# After removing directories, we always need to recreate
|
||||
if [[ $NEEDS_RECREATE -eq 1 ]] || [[ ! -d /usr/local/CyberCP/bin ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Creating/recreating CyberCP virtual environment with Python 3..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# First ensure the directory exists
|
||||
mkdir -p /usr/local/CyberCP
|
||||
|
||||
# For Ubuntu 22.04+, we need to handle virtualenv differently
|
||||
VENV_SUCCESS=0
|
||||
|
||||
# First try using python3 -m venv (more reliable on Ubuntu 22.04)
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Attempting to create virtual environment using python3 -m venv..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
virtualenv_output=$(python3 -m venv --system-site-packages /usr/local/CyberCP 2>&1)
|
||||
VENV_CODE=$?
|
||||
echo "$virtualenv_output" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
if [[ $VENV_CODE -eq 0 ]] && [[ -f /usr/local/CyberCP/bin/activate ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Virtual environment created successfully using python3 -m venv" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
VENV_SUCCESS=1
|
||||
else
|
||||
# If that fails, try virtualenv command
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] python3 -m venv failed, trying virtualenv command..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# On Ubuntu 22.04, we need to ensure proper virtualenv installation
|
||||
if [[ "$Server_OS" = "Ubuntu" ]] && [[ "$Server_OS_Version" = "22" ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Ubuntu 22.04 detected, ensuring virtualenv is properly installed..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
pip3 install --upgrade virtualenv 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
elif [[ "$Server_OS" = "CentOS" ]] && ([[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]]); then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] AlmaLinux/Rocky Linux 9/10 detected, ensuring virtualenv is properly installed..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
pip3 install --upgrade virtualenv 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
elif [[ "$Server_OS" = "AlmaLinux9" ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] AlmaLinux 9 detected, ensuring virtualenv is properly installed..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
pip3 install --upgrade virtualenv 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
|
||||
# Find the correct python3 path
|
||||
if [[ "$Server_OS" = "CentOS" ]] && ([[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]]); then
|
||||
PYTHON_PATH=$(which python3 2>/dev/null || which python3.9 2>/dev/null || echo "/usr/bin/python3")
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Using Python path: $PYTHON_PATH" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
virtualenv_output=$(virtualenv -p "$PYTHON_PATH" /usr/local/CyberCP 2>&1)
|
||||
elif [[ "$Server_OS" = "AlmaLinux9" ]]; then
|
||||
PYTHON_PATH=$(which python3 2>/dev/null || which python3.9 2>/dev/null || echo "/usr/bin/python3")
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] AlmaLinux 9 - Using Python path: $PYTHON_PATH" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
virtualenv_output=$(virtualenv -p "$PYTHON_PATH" /usr/local/CyberCP 2>&1)
|
||||
else
|
||||
virtualenv_output=$(virtualenv -p /usr/bin/python3 /usr/local/CyberCP 2>&1)
|
||||
fi
|
||||
VENV_CODE=$?
|
||||
echo "$virtualenv_output" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Check if TypeError occurred (common on Ubuntu 22.04)
|
||||
if echo "$virtualenv_output" | grep -q "TypeError"; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] WARNING: TypeError detected, attempting workaround..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Try alternative method using explicit system-site-packages
|
||||
virtualenv_output=$(virtualenv --python=/usr/bin/python3 --system-site-packages /usr/local/CyberCP 2>&1)
|
||||
VENV_CODE=$?
|
||||
echo "$virtualenv_output" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
|
||||
if [[ -f /usr/local/CyberCP/bin/activate ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Virtual environment created successfully" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
VENV_SUCCESS=1
|
||||
VENV_CODE=0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $VENV_SUCCESS -eq 0 ]]; then
|
||||
VENV_CODE=1
|
||||
fi
|
||||
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Virtualenv creation returned code: $VENV_CODE" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
if [[ $VENV_CODE -ne 0 ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] FATAL: Virtualenv creation failed with code $VENV_CODE" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
echo -e "Virtualenv creation failed. Please check the logs at /var/log/cyberpanel_upgrade_debug.log"
|
||||
exit $VENV_CODE
|
||||
fi
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] CyberCP virtualenv already exists, skipping recreation" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
echo -e "\nNo need to re-setup virtualenv at /usr/local/CyberCP...\n"
|
||||
fi
|
||||
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Removing old requirements file..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
rm -f /usr/local/requirments.txt
|
||||
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Downloading new requirements..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
Download_Requirement
|
||||
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Installing Python packages..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
if [ "$Server_OS" = "Ubuntu" ]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Ubuntu detected, activating virtual environment..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
# shellcheck disable=SC1091
|
||||
. /usr/local/CyberCP/bin/activate 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
ACTIVATE_CODE=$?
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Activate returned code: $ACTIVATE_CODE" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
Check_Return
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Upgrading setuptools and packaging..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
pip install --upgrade setuptools packaging 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Installing requirements..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
pip3 install --default-timeout=3600 --ignore-installed -r /usr/local/requirments.txt 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
PIP_CODE=$?
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Pip install returned code: $PIP_CODE" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
Check_Return
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Non-Ubuntu OS, activating virtual environment..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
# shellcheck disable=SC1091
|
||||
source /usr/local/CyberCP/bin/activate 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
ACTIVATE_CODE=$?
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Activate returned code: $ACTIVATE_CODE" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
Check_Return
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Installing requirements..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
/usr/local/CyberCP/bin/pip3 install --default-timeout=3600 --ignore-installed -r /usr/local/requirments.txt 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
PIP_CODE=$?
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Pip install returned code: $PIP_CODE" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
Check_Return
|
||||
fi
|
||||
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Verifying Django installation..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
# Test if Django is installed
|
||||
if ! /usr/local/CyberCP/bin/python -c "import django" 2>/dev/null; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] WARNING: Django not found, installing requirements again..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Re-activate virtual environment
|
||||
source /usr/local/CyberCP/bin/activate
|
||||
|
||||
# Install MySQL/MariaDB development headers for mysqlclient Python package
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Installing MySQL/MariaDB development headers..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
if [[ "$Server_OS" = "Ubuntu" ]] || [[ "$Server_OS" = "Debian" ]]; then
|
||||
# Ubuntu/Debian
|
||||
apt-get update -y
|
||||
apt-get install -y libmariadb-dev libmariadb-dev-compat pkg-config build-essential
|
||||
elif [[ "$Server_OS" =~ ^(CentOS|RHEL|AlmaLinux|RockyLinux|CloudLinux) ]]; then
|
||||
# RHEL-based systems
|
||||
if command -v dnf >/dev/null 2>&1; then
|
||||
# Remove conflicting packages first
|
||||
dnf remove -y mariadb mariadb-client-utils mariadb-server || true
|
||||
dnf remove -y MariaDB-server MariaDB-client MariaDB-devel || true
|
||||
|
||||
# Install development packages with conflict resolution
|
||||
dnf install -y --allowerasing --skip-broken --nobest mariadb-devel pkgconfig gcc python3-devel || \
|
||||
dnf install -y --allowerasing --skip-broken --nobest mysql-devel pkgconfig gcc python3-devel || \
|
||||
dnf install -y --allowerasing --skip-broken --nobest mariadb-devel mariadb-connector-c-devel pkgconfig gcc python3-devel
|
||||
else
|
||||
yum install -y mariadb-devel pkgconfig gcc python3-devel
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if mysql.h is available and create symlink if needed
|
||||
if [[ ! -f "/usr/include/mysql/mysql.h" ]] && [[ -f "/usr/include/mariadb/mysql.h" ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Creating mysql.h symlink for compatibility..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
mkdir -p /usr/include/mysql
|
||||
ln -sf /usr/include/mariadb/mysql.h /usr/include/mysql/mysql.h
|
||||
fi
|
||||
|
||||
# Re-install requirements
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Re-installing Python requirements..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
pip install --default-timeout=3600 --ignore-installed -r /usr/local/requirments.txt 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Django is properly installed" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Installing WSGI-LSAPI with optimized compilation..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Save current directory
|
||||
UPGRADE_CWD=$(pwd)
|
||||
|
||||
cd /tmp || exit
|
||||
rm -rf wsgi-lsapi-2.1*
|
||||
|
||||
wget -q https://www.litespeedtech.com/packages/lsapi/wsgi-lsapi-2.1.tgz 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
tar xf wsgi-lsapi-2.1.tgz
|
||||
cd wsgi-lsapi-2.1 || exit
|
||||
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Configuring WSGI..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
PYTHON_CFG="${CP_PYTHON:-/usr/bin/python3}"
|
||||
[[ -x "$PYTHON_CFG" ]] || PYTHON_CFG="/usr/bin/python3"
|
||||
"$PYTHON_CFG" ./configure.py 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Fix Makefile to use proper optimization flags to avoid _FORTIFY_SOURCE warnings
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Optimizing Makefile for proper compilation..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
if [[ -f Makefile ]]; then
|
||||
# Replace -O0 -g3 with -O2 -g to satisfy _FORTIFY_SOURCE
|
||||
sed -i 's/-O0 -g3/-O2 -g/g' Makefile
|
||||
# Ensure we have proper optimization flags
|
||||
if grep -q "CFLAGS" Makefile && ! grep -qF '-O2' Makefile; then
|
||||
sed -i 's/CFLAGS =/CFLAGS = -O2/' Makefile
|
||||
fi
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Makefile optimized for proper compilation" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Compiling WSGI with optimized flags..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] (Upstream WSGI source may show harmless strncpy/gstate warnings; build can still succeed.)" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
make clean 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
make 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Installing lswsgi binary..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
rm -f /usr/local/CyberCP/bin/lswsgi
|
||||
cp lswsgi /usr/local/CyberCP/bin/
|
||||
chmod +x /usr/local/CyberCP/bin/lswsgi
|
||||
|
||||
# Return to original directory
|
||||
cd "$UPGRADE_CWD" || cd /root
|
||||
|
||||
# Final verification
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Running final verification..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
if /usr/local/CyberCP/bin/python -c "import django" 2>/dev/null && [[ -f /usr/local/CyberCP/bin/lswsgi ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] All components successfully installed!" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] WARNING: Some components may be missing, check logs" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Main_Upgrade function completed" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
}
|
||||
|
||||
# Sync /usr/local/CyberCP to the latest commit of the upgrade branch so Version Management
|
||||
# page shows Current commit matching Latest (avoids "please upgrade" when upgrade already ran).
|
||||
# Backs up and restores CyberCP/settings.py so production DB/config are not overwritten by the repo.
|
||||
43
upgrade_modules/09_sync.sh
Normal file
43
upgrade_modules/09_sync.sh
Normal file
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env bash
|
||||
# CyberPanel upgrade – sync CyberCP to latest commit. Sourced by cyberpanel_upgrade.sh.
|
||||
|
||||
Sync_CyberCP_To_Latest() {
|
||||
if [[ ! -d /usr/local/CyberCP/.git ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] No .git in /usr/local/CyberCP, skipping sync" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
return 0
|
||||
fi
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Syncing /usr/local/CyberCP to latest commit for branch: $Branch_Name" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
# Backup production settings so sync does not overwrite DB credentials / local config
|
||||
if [[ -f /usr/local/CyberCP/CyberCP/settings.py ]]; then
|
||||
cp /usr/local/CyberCP/CyberCP/settings.py /tmp/cyberpanel_settings_backup.py
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Backed up settings.py for restore after sync" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
(
|
||||
cd /usr/local/CyberCP
|
||||
git fetch origin 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
if git show-ref -q "refs/remotes/origin/$Branch_Name"; then
|
||||
git checkout -B "$Branch_Name" "origin/$Branch_Name" 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
else
|
||||
git checkout "$Branch_Name" 2>/dev/null || true
|
||||
git pull --ff-only origin "$Branch_Name" 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log || true
|
||||
fi
|
||||
)
|
||||
local sync_code=$?
|
||||
# Restore production settings so panel keeps working (DB, secrets, etc.)
|
||||
if [[ -f /tmp/cyberpanel_settings_backup.py ]]; then
|
||||
cp /tmp/cyberpanel_settings_backup.py /usr/local/CyberCP/CyberCP/settings.py
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Restored settings.py after sync" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
# LiteSpeed serves /static/ from public/static/; ensure it has latest baseTemplate static files (e.g. dashboard JS)
|
||||
if [[ -d /usr/local/CyberCP/public/static ]] && [[ -d /usr/local/CyberCP/baseTemplate/static/baseTemplate ]]; then
|
||||
rsync -a /usr/local/CyberCP/baseTemplate/static/baseTemplate/ /usr/local/CyberCP/public/static/baseTemplate/ 2>/dev/null || \
|
||||
cp -r /usr/local/CyberCP/baseTemplate/static/baseTemplate/* /usr/local/CyberCP/public/static/baseTemplate/ 2>/dev/null || true
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Synced baseTemplate static to public/static" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
if [[ $sync_code -eq 0 ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Sync completed. Current HEAD: $(git -C /usr/local/CyberCP rev-parse HEAD 2>/dev/null || echo 'unknown')" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Sync returned code $sync_code (non-fatal)" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
336
upgrade_modules/10_post_tweak.sh
Normal file
336
upgrade_modules/10_post_tweak.sh
Normal file
@@ -0,0 +1,336 @@
|
||||
#!/usr/bin/env bash
|
||||
# CyberPanel upgrade – post-upgrade system tweaks (PHP, LSWS, SnappyMail, etc.). Sourced by cyberpanel_upgrade.sh.
|
||||
|
||||
Post_Upgrade_System_Tweak() {
|
||||
if [[ "$Server_OS" = "CentOS" ]] ; then
|
||||
|
||||
#for cenots 7/8
|
||||
if [[ "$Server_OS_Version" = "7" ]] ; then
|
||||
sed -i 's|error_reporting = E_ALL \& ~E_DEPRECATED \& ~E_STRICT|error_reporting = E_ALL \& ~E_DEPRECATED \& ~E_STRICT|g' /usr/local/lsws/{lsphp72,lsphp73}/etc/php.ini
|
||||
#fix php.ini & issue
|
||||
if ! yum list installed lsphp74-devel ; then
|
||||
yum install -y lsphp74-devel
|
||||
fi
|
||||
if [[ ! -f /usr/local/lsws/lsphp74/lib64/php/modules/zip.so ]] ; then
|
||||
if yum list installed libzip-devel >/dev/null 2>&1 ; then
|
||||
yum remove -y libzip-devel
|
||||
fi
|
||||
yum install -y https://cyberpanel.sh/misc/libzip-0.11.2-6.el7.psychotic.x86_64.rpm
|
||||
yum install -y https://cyberpanel.sh/misc/libzip-devel-0.11.2-6.el7.psychotic.x86_64.rpm
|
||||
yum install lsphp74-devel
|
||||
if [[ ! -d /usr/local/lsws/lsphp74/tmp ]]; then
|
||||
mkdir /usr/local/lsws/lsphp74/tmp
|
||||
fi
|
||||
/usr/local/lsws/lsphp74/bin/pecl channel-update pecl.php.net
|
||||
/usr/local/lsws/lsphp74/bin/pear config-set temp_dir /usr/local/lsws/lsphp74/tmp
|
||||
if /usr/local/lsws/lsphp74/bin/pecl install zip ; then
|
||||
echo "extension=zip.so" >/usr/local/lsws/lsphp74/etc/php.d/20-zip.ini
|
||||
chmod 755 /usr/local/lsws/lsphp74/lib64/php/modules/zip.so
|
||||
else
|
||||
echo -e "\nlsphp74-zip compilation failed..."
|
||||
fi
|
||||
#fix old legacy lsphp74-zip issue on centos 7
|
||||
fi
|
||||
|
||||
|
||||
#for centos 7
|
||||
elif [[ "$Server_OS_Version" = "8" ]] ; then
|
||||
:
|
||||
#for centos 8
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$Server_OS" = "Ubuntu" ]] ; then
|
||||
|
||||
if ! dpkg -l lsphp74-dev >/dev/null 2>&1 ; then
|
||||
apt install -y lsphp74-dev
|
||||
fi
|
||||
|
||||
if [[ ! -f /usr/sbin/ipset ]] ; then
|
||||
ln -s /sbin/ipset /usr/sbin/ipset
|
||||
fi
|
||||
|
||||
#for ubuntu 18/20
|
||||
if [[ "$Server_OS_Version" = "18" ]] ; then
|
||||
:
|
||||
#for ubuntu 18
|
||||
elif [[ "$Server_OS_Version" = "20" ]] ; then
|
||||
:
|
||||
#for ubuntu 20
|
||||
fi
|
||||
fi
|
||||
|
||||
sed -i "s|lsws-5.3.8|lsws-$LSWS_Stable_Version|g" /usr/local/CyberCP/serverStatus/serverStatusUtil.py
|
||||
sed -i "s|lsws-5.4.2|lsws-$LSWS_Stable_Version|g" /usr/local/CyberCP/serverStatus/serverStatusUtil.py
|
||||
sed -i "s|lsws-5.3.5|lsws-$LSWS_Stable_Version|g" /usr/local/CyberCP/serverStatus/serverStatusUtil.py
|
||||
sed -i "s|lsws-6.0|lsws-$LSWS_Stable_Version|g" /usr/local/CyberCP/serverStatus/serverStatusUtil.py
|
||||
sed -i "s|lsws-6.3.4|lsws-$LSWS_Stable_Version|g" /usr/local/CyberCP/serverStatus/serverStatusUtil.py
|
||||
|
||||
if [[ "$Server_Country" = "CN" ]] ; then
|
||||
sed -i 's|https://www.litespeedtech.com/|https://cyberpanel.sh/www.litespeedtech.com/|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py
|
||||
sed -i 's|http://license.litespeedtech.com/|https://cyberpanel.sh/license.litespeedtech.com/|g' /usr/local/CyberCP/serverStatus/serverStatusUtil.py
|
||||
fi
|
||||
|
||||
sed -i 's|python2|python|g' /usr/bin/adminPass
|
||||
chmod 700 /usr/bin/adminPass
|
||||
|
||||
rm -f /usr/bin/php
|
||||
ln -s /usr/local/lsws/lsphp74/bin/php /usr/bin/php
|
||||
|
||||
if [[ -f /etc/cyberpanel/webadmin_passwd ]]; then
|
||||
chmod 600 /etc/cyberpanel/webadmin_passwd
|
||||
fi
|
||||
|
||||
chown lsadm:lsadm /usr/local/lsws/admin/conf/htpasswd
|
||||
chmod 600 /usr/local/lsws/admin/conf/htpasswd
|
||||
|
||||
if [[ -f /etc/pure-ftpd/pure-ftpd.conf ]]; then
|
||||
sed -i 's|NoAnonymous no|NoAnonymous yes|g' /etc/pure-ftpd/pure-ftpd.conf
|
||||
fi
|
||||
|
||||
Tmp_Output=$(timeout 3 openssl s_client -connect 127.0.0.1:8090 2>/dev/null)
|
||||
if echo "$Tmp_Output" | grep -q "mail@example.com" ; then
|
||||
# it is using default installer generated cert
|
||||
Regenerate_Cert 8090
|
||||
fi
|
||||
|
||||
|
||||
Tmp_Output=$(timeout 3 openssl s_client -connect 127.0.0.1:7080 2>/dev/null)
|
||||
if echo "$Tmp_Output" | grep -q "mail@example.com" ; then
|
||||
Regenerate_Cert 7080
|
||||
fi
|
||||
|
||||
if [[ ! -f /usr/bin/cyberpanel_utility ]]; then
|
||||
wget -q -O /usr/bin/cyberpanel_utility https://cyberpanel.sh/misc/cyberpanel_utility.sh
|
||||
chmod 700 /usr/bin/cyberpanel_utility
|
||||
fi
|
||||
|
||||
if [[ -f /etc/cyberpanel/watchdog.sh ]] ; then
|
||||
watchdog kill
|
||||
rm -f /etc/cyberpanel/watchdog.sh
|
||||
rm -f /usr/local/bin/watchdog
|
||||
wget -O /etc/cyberpanel/watchdog.sh "${Git_Content_URL}/${Branch_Name}/CPScripts/watchdog.sh"
|
||||
chmod 700 /etc/cyberpanel/watchdog.sh
|
||||
ln -s /etc/cyberpanel/watchdog.sh /usr/local/bin/watchdog
|
||||
watchdog status
|
||||
fi
|
||||
|
||||
|
||||
rm -f /usr/local/composer.sh
|
||||
rm -f /usr/local/requirments.txt
|
||||
|
||||
chown -R cyberpanel:cyberpanel /usr/local/CyberCP/lib
|
||||
chown -R cyberpanel:cyberpanel /usr/local/CyberCP/lib64
|
||||
|
||||
# Fix missing lsphp binary in /usr/local/lscp/fcgi-bin/ after upgrade
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Checking and restoring lsphp binary if missing..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
if [[ ! -f /usr/local/lscp/fcgi-bin/lsphp ]] || [[ ! -s /usr/local/lscp/fcgi-bin/lsphp ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] lsphp binary missing or empty, attempting to restore..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Ensure fcgi-bin directory exists
|
||||
mkdir -p /usr/local/lscp/fcgi-bin
|
||||
|
||||
# Find the latest available PHP version and use it
|
||||
PHP_RESTORED=0
|
||||
|
||||
# Try to find the latest lsphp version (check from newest to oldest)
|
||||
# Priority: 85 (beta), 84, 83, 82, 81, 80, 74
|
||||
for PHP_VER in 85 84 83 82 81 80 74; do
|
||||
if [[ -f /usr/local/lsws/lsphp${PHP_VER}/bin/lsphp ]]; then
|
||||
# Try to create symlink first (preferred)
|
||||
if ln -sf /usr/local/lsws/lsphp${PHP_VER}/bin/lsphp /usr/local/lscp/fcgi-bin/lsphp 2>/dev/null; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] lsphp symlink created from lsphp${PHP_VER}" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
else
|
||||
# If symlink fails, copy the file
|
||||
cp -f /usr/local/lsws/lsphp${PHP_VER}/bin/lsphp /usr/local/lscp/fcgi-bin/lsphp
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] lsphp binary copied from lsphp${PHP_VER}" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
chown root:root /usr/local/lscp/fcgi-bin/lsphp
|
||||
chmod 755 /usr/local/lscp/fcgi-bin/lsphp
|
||||
PHP_RESTORED=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# If no lsphp version found, try php binary as fallback
|
||||
if [[ $PHP_RESTORED -eq 0 ]]; then
|
||||
for PHP_VER in 83 82 81 80 74 73 72; do
|
||||
if [[ -f /usr/local/lsws/lsphp${PHP_VER}/bin/php ]]; then
|
||||
# Try to create symlink first (preferred)
|
||||
if ln -sf /usr/local/lsws/lsphp${PHP_VER}/bin/php /usr/local/lscp/fcgi-bin/lsphp 2>/dev/null; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] lsphp symlink created from php${PHP_VER} (lsphp fallback)" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
else
|
||||
# If symlink fails, copy the file
|
||||
cp -f /usr/local/lsws/lsphp${PHP_VER}/bin/php /usr/local/lscp/fcgi-bin/lsphp
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] lsphp binary copied from php${PHP_VER} (lsphp fallback)" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
chown root:root /usr/local/lscp/fcgi-bin/lsphp
|
||||
chmod 755 /usr/local/lscp/fcgi-bin/lsphp
|
||||
PHP_RESTORED=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# If no lsphp version found, try admin_php5 as fallback
|
||||
if [[ $PHP_RESTORED -eq 0 ]]; then
|
||||
if [[ -f /usr/local/lscp/admin/fcgi-bin/admin_php5 ]]; then
|
||||
cp -f /usr/local/lscp/admin/fcgi-bin/admin_php5 /usr/local/lscp/fcgi-bin/lsphp
|
||||
chown root:root /usr/local/lscp/fcgi-bin/lsphp
|
||||
chmod 755 /usr/local/lscp/fcgi-bin/lsphp
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] lsphp binary restored from admin_php5 (fallback)" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
elif [[ -f /usr/local/lscp/admin/fcgi-bin/admin_php ]]; then
|
||||
cp -f /usr/local/lscp/admin/fcgi-bin/admin_php /usr/local/lscp/fcgi-bin/lsphp
|
||||
chown root:root /usr/local/lscp/fcgi-bin/lsphp
|
||||
chmod 755 /usr/local/lscp/fcgi-bin/lsphp
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] lsphp binary restored from admin_php (fallback)" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
elif [[ -f /usr/local/lsws/admin/fcgi-bin/admin_php5 ]]; then
|
||||
cp -f /usr/local/lsws/admin/fcgi-bin/admin_php5 /usr/local/lscp/fcgi-bin/lsphp
|
||||
chown root:root /usr/local/lscp/fcgi-bin/lsphp
|
||||
chmod 755 /usr/local/lscp/fcgi-bin/lsphp
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] lsphp binary restored from lsws admin_php5 (fallback)" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] ERROR: Could not find any PHP binary to restore lsphp" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create symlinks if they don't exist
|
||||
if [[ -f /usr/local/lscp/fcgi-bin/lsphp ]]; then
|
||||
if [[ ! -f /usr/local/lscp/fcgi-bin/lsphp4 ]]; then
|
||||
ln -sf ./lsphp /usr/local/lscp/fcgi-bin/lsphp4
|
||||
fi
|
||||
if [[ ! -f /usr/local/lscp/fcgi-bin/lsphp5 ]]; then
|
||||
ln -sf ./lsphp /usr/local/lscp/fcgi-bin/lsphp5
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fix missing lscpd binary in /usr/local/lscp/bin/ after upgrade
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Checking and restoring lscpd binary if missing..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
if [[ ! -f /usr/local/lscp/bin/lscpd ]] || [[ ! -s /usr/local/lscp/bin/lscpd ]]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] lscpd binary missing or empty, attempting to restore..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Ensure lscp bin directory exists
|
||||
mkdir -p /usr/local/lscp/bin
|
||||
|
||||
# Select the correct lscpd binary based on OS and version
|
||||
lscpd_selection='lscpd-0.3.1'
|
||||
|
||||
# Check if this is an ARM system
|
||||
if uname -a | grep -q 'aarch64'; then
|
||||
lscpd_selection='lscpd.aarch64'
|
||||
else
|
||||
# For x86_64 systems, check Ubuntu version
|
||||
if [[ "$Server_OS" = "Ubuntu" ]] && [[ -f /etc/lsb-release ]]; then
|
||||
ubuntu_version=$(grep 'DISTRIB_RELEASE' /etc/lsb-release | cut -d'=' -f2 | cut -d'.' -f1)
|
||||
if [[ "$ubuntu_version" = "22" ]] || [[ "$ubuntu_version" = "24" ]]; then
|
||||
lscpd_selection='lscpd.0.4.0'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Selected lscpd binary: $lscpd_selection" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Copy the selected binary from CyberCP to lscp bin
|
||||
if [[ -f /usr/local/CyberCP/${lscpd_selection} ]]; then
|
||||
cp -f /usr/local/CyberCP/${lscpd_selection} /usr/local/lscp/bin/${lscpd_selection}
|
||||
rm -f /usr/local/lscp/bin/lscpd
|
||||
mv /usr/local/lscp/bin/${lscpd_selection} /usr/local/lscp/bin/lscpd
|
||||
chmod 755 /usr/local/lscp/bin/lscpd
|
||||
chown root:root /usr/local/lscp/bin/lscpd
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] lscpd binary restored successfully from ${lscpd_selection}" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] ERROR: Could not find lscpd source binary ${lscpd_selection} in /usr/local/CyberCP/" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] lscpd binary exists and is valid" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
|
||||
if [[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]] || [[ "$Server_OS_Version" = "18" ]] || [[ "$Server_OS_Version" = "8" ]] || [[ "$Server_OS_Version" = "20" ]] || [[ "$Server_OS_Version" = "24" ]]; then
|
||||
echo "PYTHONHOME=/usr" > /usr/local/lscp/conf/pythonenv.conf
|
||||
else
|
||||
# Uncomment and use the following lines if necessary for other OS versions
|
||||
# rsync -av --ignore-existing /usr/lib64/python3.9/ /usr/local/CyberCP/lib64/python3.9/
|
||||
# Check_Return
|
||||
:
|
||||
fi
|
||||
|
||||
# Fix SnappyMail directory permissions for Ubuntu 24.04 and other systems
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Checking SnappyMail directories..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Migrate data from old rainloop folder to new snappymail folder (2.4.4 -> 2.5.5 upgrade)
|
||||
if [ -d "/usr/local/lscp/cyberpanel/rainloop/data" ] && [ "$(ls -A /usr/local/lscp/cyberpanel/rainloop/data 2>/dev/null)" ]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Migrating rainloop data to snappymail..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Check if snappymail data already exists with content
|
||||
if [ -d "/usr/local/lscp/cyberpanel/snappymail/data" ] && [ -d "/usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/configs" ]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] SnappyMail data already exists, skipping migration" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
else
|
||||
# Create SnappyMail data directories if they don't exist
|
||||
mkdir -p /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/configs/
|
||||
mkdir -p /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/domains/
|
||||
mkdir -p /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/storage/
|
||||
mkdir -p /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/temp/
|
||||
mkdir -p /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/cache/
|
||||
|
||||
# Migrate data using rsync (preserves permissions and ownership)
|
||||
rsync -av --ignore-existing /usr/local/lscp/cyberpanel/rainloop/data/ /usr/local/lscp/cyberpanel/snappymail/data/ 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Successfully migrated rainloop data to snappymail" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Update include.php to use snappymail path
|
||||
if [ -f "/usr/local/CyberCP/public/snappymail/include.php" ]; then
|
||||
sed -i 's|/usr/local/lscp/cyberpanel/rainloop/data|/usr/local/lscp/cyberpanel/snappymail/data|g' /usr/local/CyberCP/public/snappymail/include.php
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Updated include.php to use snappymail data path" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] WARNING: Data migration completed with errors" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] No old rainloop data found, creating new SnappyMail directories..." | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Create SnappyMail data directories if they don't exist
|
||||
mkdir -p /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/configs/
|
||||
mkdir -p /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/domains/
|
||||
mkdir -p /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/storage/
|
||||
mkdir -p /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/temp/
|
||||
mkdir -p /usr/local/lscp/cyberpanel/snappymail/data/_data_/_default_/cache/
|
||||
fi
|
||||
|
||||
# Ensure proper ownership for SnappyMail data directories
|
||||
if id -u lscpd >/dev/null 2>&1; then
|
||||
chown -R lscpd:lscpd /usr/local/lscp/cyberpanel/snappymail/
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Set SnappyMail ownership to lscpd:lscpd" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
else
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] WARNING: lscpd user not found, skipping ownership change" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
|
||||
# Set proper permissions for SnappyMail data directories (group writable)
|
||||
chmod -R 775 /usr/local/lscp/cyberpanel/snappymail/data/
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Set SnappyMail data directory permissions to 775 (group writable)" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Ensure web server users are in the lscpd group for access
|
||||
usermod -a -G lscpd nobody 2>/dev/null || true
|
||||
|
||||
# Fix SnappyMail public directory ownership (critical fix)
|
||||
chown -R lscpd:lscpd /usr/local/CyberCP/public/snappymail/data 2>/dev/null || true
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Added web server users to lscpd group and fixed SnappyMail ownership" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
|
||||
# Force phpMyAdmin to use 127.0.0.1 (TCP) so it shows the same MariaDB version as CLI (main instance on 3306)
|
||||
if [ -f /usr/local/CyberCP/public/phpmyadmin/config.inc.php ]; then
|
||||
if ! grep -q "\$cfg\['Servers'\]\[\$i\]\['host'\] = '127.0.0.1'" /usr/local/CyberCP/public/phpmyadmin/config.inc.php 2>/dev/null; then
|
||||
sed -i "/SignonURL/a \$cfg['Servers'][\$i]['host'] = '127.0.0.1';\n\$cfg['Servers'][\$i]['port'] = '3306';" /usr/local/CyberCP/public/phpmyadmin/config.inc.php 2>/dev/null || true
|
||||
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Set phpMyAdmin server host to 127.0.0.1" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
fi
|
||||
if [ -f /usr/local/CyberCP/public/phpmyadmin/phpmyadminsignin.php ]; then
|
||||
sed -i "/trim.*\$_POST.*host.*localhost/s/'localhost'/'127.0.0.1'/g" /usr/local/CyberCP/public/phpmyadmin/phpmyadminsignin.php 2>/dev/null || true
|
||||
grep -q "127.0.0.1" /usr/local/CyberCP/public/phpmyadmin/phpmyadminsignin.php && echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] phpMyAdmin signon default host set to 127.0.0.1" | tee -a /var/log/cyberpanel_upgrade_debug.log
|
||||
fi
|
||||
|
||||
systemctl restart lscpd
|
||||
|
||||
}
|
||||
|
||||
122
upgrade_modules/11_display_final.sh
Normal file
122
upgrade_modules/11_display_final.sh
Normal file
@@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env bash
|
||||
# CyberPanel upgrade – final display (banner, next steps). Sourced by cyberpanel_upgrade.sh.
|
||||
|
||||
Post_Install_Display_Final_Info() {
|
||||
echo -e "\n"
|
||||
# Fixed box width (109 chars). ASCII-only borders (| - +) so right edge renders solid in all terminals.
|
||||
BOX_W=109
|
||||
# 109 dashes for top/bottom border (no Unicode = so line is consistently filled)
|
||||
_br() { echo "+-------------------------------------------------------------------------------------------------------------+"; }
|
||||
_bl() { echo "+-------------------------------------------------------------------------------------------------------------+"; }
|
||||
_b() { local s="$1"; [[ ${#s} -gt $BOX_W ]] && s="${s:0:BOX_W}"; printf '|%-*s|\n' "$BOX_W" "$s"; }
|
||||
_br
|
||||
_b ""
|
||||
_b " █████████ █████ ███████████ ████"
|
||||
_b " ███▒▒▒▒▒███ ▒▒███ ▒▒███▒▒▒▒▒███ ▒▒███"
|
||||
_b " ███ ▒▒▒ █████ ████ ▒███████ ██████ ████████ ▒███ ▒███ ██████ ████████ ██████ ▒███"
|
||||
_b " ▒███ ▒▒███ ▒███ ▒███▒▒███ ███▒▒███▒▒███▒▒███ ▒██████████ ▒▒▒▒▒███ ▒▒███▒▒███ ███▒▒███ ▒███"
|
||||
_b " ▒███ ▒███ ▒███ ▒███ ▒███▒███████ ▒███ ▒▒▒ ▒███▒▒▒▒▒▒ ███████ ▒███ ▒███ ▒███████ ▒███"
|
||||
_b " ▒▒███ ███ ▒███ ▒███ ▒███ ▒███▒███▒▒▒ ▒███ ▒███ ███▒▒███ ▒███ ▒███ ▒███▒▒▒ ▒███"
|
||||
_b " ▒▒█████████ ▒▒███████ ████████ ▒▒██████ █████ █████ ▒▒████████ ████ █████▒▒██████ █████"
|
||||
_b " ▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒███ ▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒ ▒▒▒▒▒ ▒▒▒▒▒ ▒▒▒▒▒▒▒▒ ▒▒▒▒ ▒▒▒▒▒ ▒▒▒▒▒▒ ▒▒▒▒▒"
|
||||
_b " ███ ▒███"
|
||||
_b " ▒▒██████"
|
||||
_b " ▒▒▒▒▒▒"
|
||||
_b " *** UPGRADE COMPLETED SUCCESSFULLY! ***"
|
||||
_b ""
|
||||
_bl
|
||||
|
||||
Panel_Port=$(cat /usr/local/lscp/conf/bind.conf)
|
||||
if [[ $Panel_Port = "" ]] ; then
|
||||
Panel_Port="8090"
|
||||
fi
|
||||
|
||||
# Resolve server IP for remote access URL (avoid empty Remote: https://:2087)
|
||||
if [[ -z "$SERVER_IP" ]]; then
|
||||
SERVER_IP=$(hostname -I 2>/dev/null | awk '{print $1}')
|
||||
fi
|
||||
if [[ -z "$SERVER_IP" ]]; then
|
||||
SERVER_IP=$(ip -4 route get 1 2>/dev/null | awk '/src/ {print $7; exit}')
|
||||
fi
|
||||
if [[ -z "$SERVER_IP" ]]; then
|
||||
SERVER_IP=$(curl -s --max-time 3 ifconfig.me 2>/dev/null || curl -s --max-time 3 icanhazip.com 2>/dev/null)
|
||||
fi
|
||||
if [[ -z "$SERVER_IP" ]]; then
|
||||
SERVER_IP="YOUR_SERVER_IP"
|
||||
fi
|
||||
|
||||
# Actual MariaDB server version (what phpMyAdmin will show)
|
||||
# Actual server version (use --skip-ssl: 11.x client requires SSL by default, 10.x server may not offer it)
|
||||
MARIADB_ACTUAL_VER=""
|
||||
if command -v mariadb >/dev/null 2>&1; then
|
||||
MARIADB_ACTUAL_VER=$(mariadb --skip-ssl -e "SELECT @@version;" -sN 2>/dev/null | head -1)
|
||||
fi
|
||||
[[ -z "$MARIADB_ACTUAL_VER" ]] && command -v mysql >/dev/null 2>&1 && MARIADB_ACTUAL_VER=$(mysql --skip-ssl -e "SELECT @@version;" -sN 2>/dev/null | head -1)
|
||||
[[ -z "$MARIADB_ACTUAL_VER" ]] && MARIADB_ACTUAL_VER="${MARIADB_VER:-unknown}"
|
||||
|
||||
# Test if CyberPanel is accessible
|
||||
echo -e "\n🔍 Testing CyberPanel accessibility..."
|
||||
|
||||
# Check if lscpd service is running
|
||||
if systemctl is-active --quiet lscpd 2>/dev/null; then
|
||||
_br
|
||||
_b ""
|
||||
_b " ACCESS YOUR CYBERPANEL:"
|
||||
_b ""
|
||||
_b " Local: https://127.0.0.1:${Panel_Port#*:}"
|
||||
_b " Remote: https://${SERVER_IP}:${Panel_Port#*:}"
|
||||
_b ""
|
||||
_b " Default Login: admin / 1234567890"
|
||||
_b " >> Please change the default password immediately!"
|
||||
_b ""
|
||||
_bl
|
||||
|
||||
# Binary confirmation + versions (ASCII-only so box alignment is correct)
|
||||
echo -e "\n"
|
||||
_br
|
||||
_b ""
|
||||
_b " UPGRADE STATUS: [====================================================] 100%"
|
||||
_b ""
|
||||
_b " [OK] All components installed successfully"
|
||||
_b " [OK] Python dependencies resolved"
|
||||
_b " [OK] WSGI-LSAPI compiled with optimizations"
|
||||
_b " [OK] CyberPanel service is running"
|
||||
_b " [OK] Web interface is accessible"
|
||||
_b ""
|
||||
_b " CyberPanel: ${Branch_Name:-unknown}"
|
||||
_b " Database (MariaDB): ${MARIADB_ACTUAL_VER}"
|
||||
_b ""
|
||||
_b " *** UPGRADE COMPLETED SUCCESSFULLY! ***"
|
||||
_b ""
|
||||
_bl
|
||||
|
||||
else
|
||||
echo -e "CyberPanel may not be running properly. Please check the logs."
|
||||
echo -e "\n"
|
||||
_br
|
||||
_b ""
|
||||
_b " UPGRADE COMPLETED WITH WARNINGS"
|
||||
_b ""
|
||||
_b " - CyberPanel files have been updated"
|
||||
_b " - Some services may need manual restart"
|
||||
_b " - Please check logs at /var/log/cyberpanel_upgrade_debug.log"
|
||||
_b ""
|
||||
_b " Try running: systemctl restart lscpd"
|
||||
_b ""
|
||||
_bl
|
||||
fi
|
||||
|
||||
echo -e "\n📋 Next Steps:"
|
||||
echo -e " 1. Access your CyberPanel at the URL above"
|
||||
echo -e " 2. Change the default admin password"
|
||||
echo -e " 3. Configure your domains and websites"
|
||||
echo -e " 4. Check system status in the dashboard"
|
||||
echo -e " 5. Check DB version with: mariadb -V (use mariadb, not mysql, to avoid deprecation warning)"
|
||||
echo -e " 6. Pre-upgrade DB backup (if created): /root/cyberpanel_mariadb_backups/"
|
||||
echo -e " 7. One-liner: --backup-db (always backup DB), --no-backup-db (skip); omit = prompt. --migrate-to-utf8 for UTF-8 (only if your apps support it)"
|
||||
echo -e " 8. If you downgrade to MariaDB 10.11.16, server charset stays latin1 for backward compatibility."
|
||||
|
||||
echo -e "\n🧹 Cleaning up temporary files..."
|
||||
rm -rf /root/cyberpanel_upgrade_tmp
|
||||
echo -e "✅ Cleanup completed\n"
|
||||
}
|
||||
Reference in New Issue
Block a user