diff --git a/baseTemplate/static/baseTemplate/custom-js/system-status.js b/baseTemplate/static/baseTemplate/custom-js/system-status.js
index b4cf11a11..4cdc013aa 100644
--- a/baseTemplate/static/baseTemplate/custom-js/system-status.js
+++ b/baseTemplate/static/baseTemplate/custom-js/system-status.js
@@ -696,6 +696,12 @@ app.controller('versionManagment', function ($scope, $http, $timeout) {
$scope.updateStarted = false;
$scope.updateFinish = true;
$scope.couldNotConnect = true;
+ var startPct = (typeof response.data.progress !== 'undefined' && isFinite(response.data.progress))
+ ? response.data.progress : 0;
+ var progEl = document.getElementById('upgradeProgressLog');
+ if (progEl) {
+ progEl.innerText = 'Upgrade Progress: ' + startPct + '%';
+ }
getUpgradeStatus();
} else {
$scope.updateError = false;
@@ -740,6 +746,12 @@ app.controller('versionManagment', function ($scope, $http, $timeout) {
function ListInitialDatas(response) {
console.log(response.data.upgradeLog);
+ var pct = (typeof response.data.progress !== 'undefined' && isFinite(response.data.progress))
+ ? response.data.progress : 0;
+ var progEl = document.getElementById('upgradeProgressLog');
+ if (progEl) {
+ progEl.innerText = 'Upgrade Progress: ' + pct + '%';
+ }
if (response.data.upgradeStatus === 1) {
@@ -753,6 +765,9 @@ app.controller('versionManagment', function ($scope, $http, $timeout) {
$scope.updateStarted = true;
$scope.updateFinish = false;
$scope.couldNotConnect = true;
+ if (progEl) {
+ progEl.innerText = 'Upgrade Progress: 100%';
+ }
} else {
$scope.upgradelogBox = false;
diff --git a/baseTemplate/templates/baseTemplate/versionManagment.html b/baseTemplate/templates/baseTemplate/versionManagment.html
index 3d1d745bd..74475d0bf 100644
--- a/baseTemplate/templates/baseTemplate/versionManagment.html
+++ b/baseTemplate/templates/baseTemplate/versionManagment.html
@@ -414,7 +414,7 @@
{% if fork_remote_commit %}
- {% trans "Your fork — latest on GitHub" %}
+ {% trans "Your repository (git origin) — latest on GitHub" %}
{{ fork_remote_commit_short }}
{% if fork_commit_url %}
diff --git a/baseTemplate/views.py b/baseTemplate/views.py
index 871a8551e..b67ab7e81 100644
--- a/baseTemplate/views.py
+++ b/baseTemplate/views.py
@@ -432,7 +432,7 @@ def upgrade(request):
background = ApplicationInstaller('UpgradeCP', extraArgs)
background.start()
- adminData = {"upgrade": 1}
+ adminData = {"upgrade": 1, "progress": 0}
json_data = json.dumps(adminData)
return HttpResponse(json_data)
@@ -442,6 +442,21 @@ def upgrade(request):
return HttpResponse(json_data)
+def _read_upgrade_progress_percent():
+ """Read JSON sidecar written by plogical.upgrade.Upgrade.write_upgrade_progress."""
+ try:
+ from plogical.upgrade import Upgrade
+ prog_path = getattr(Upgrade, 'ProgressPathNew', '/home/cyberpanel/upgrade_progress')
+ if os.path.isfile(prog_path):
+ with open(prog_path, 'r') as rf:
+ data = json.loads(rf.read())
+ v = int(data.get('pct', 0))
+ return max(0, min(100, v))
+ except (ValueError, TypeError, json.JSONDecodeError, OSError, KeyError):
+ pass
+ return 0
+
+
def upgradeStatus(request):
try:
val = request.session['userID']
@@ -456,28 +471,49 @@ def upgradeStatus(request):
from plogical.upgrade import Upgrade
path = Upgrade.LogPathNew
+ prog_path = getattr(Upgrade, 'ProgressPathNew', '/home/cyberpanel/upgrade_progress')
+ pct = _read_upgrade_progress_percent()
- try:
- upgradeLog = ProcessUtilities.outputExecutioner(f'cat {path}')
- except:
+ upgradeLog = None
+ if os.path.isfile(path):
+ try:
+ upgradeLog = ProcessUtilities.outputExecutioner(f'cat {path}')
+ except BaseException:
+ upgradeLog = None
+
+ if upgradeLog is None or not isinstance(upgradeLog, str):
+ upgradeLog = None
+ elif upgradeLog.strip().startswith('cat:'):
+ upgradeLog = None
+
+ if upgradeLog is None:
final_json = json.dumps({'finished': 0, 'upgradeStatus': 1,
'error_message': "None",
- 'upgradeLog': "Upgrade Just started.."})
+ 'upgradeLog': "Waiting for upgrade log…",
+ 'progress': pct})
return HttpResponse(final_json)
if upgradeLog.find("Upgrade Completed") > -1:
command = f'rm -rf {path}'
ProcessUtilities.executioner(command)
+ try:
+ if os.path.isfile(prog_path):
+ os.remove(prog_path)
+ except OSError:
+ pass
final_json = json.dumps({'finished': 1, 'upgradeStatus': 1,
'error_message': "None",
- 'upgradeLog': upgradeLog})
+ 'upgradeLog': upgradeLog,
+ 'progress': 100})
return HttpResponse(final_json)
else:
+ pct = _read_upgrade_progress_percent()
final_json = json.dumps({'finished': 0, 'upgradeStatus': 1,
'error_message': "None",
- 'upgradeLog': upgradeLog})
+ 'upgradeLog': upgradeLog,
+ 'progress': pct})
return HttpResponse(final_json)
except BaseException as msg:
final_dic = {'upgradeStatus': 0, 'error_message': str(msg)}
diff --git a/plogical/upgrade.py b/plogical/upgrade.py
index fd5dcd6d8..15c43ef51 100644
--- a/plogical/upgrade.py
+++ b/plogical/upgrade.py
@@ -325,6 +325,7 @@ class Upgrade:
FromCloud = 0
SnappyVersion = '2.38.2'
LogPathNew = '/home/cyberpanel/upgrade_logs'
+ ProgressPathNew = '/home/cyberpanel/upgrade_progress'
SoftUpgrade = 0
AdminACL = '{"adminStatus":1, "versionManagement": 1, "createNewUser": 1, "listUsers": 1, "deleteUser":1 , "resellerCenter": 1, ' \
@@ -354,6 +355,40 @@ class Upgrade:
' "restoreBackup": 0, "addDeleteDestinations": 0, "scheduleBackups": 0, "remoteBackups": 0, "googleDriveBackups": 1, "manageSSL": 1, ' \
'"hostnameSSL": 0, "mailServerSSL": 0 }'
+ @staticmethod
+ def write_upgrade_progress(pct, monotonic=False):
+ """Persist 0–100 for Version Management polling; optional monotonic increase."""
+ try:
+ pct = int(pct)
+ pct = max(0, min(100, pct))
+ parent = os.path.dirname(Upgrade.ProgressPathNew)
+ if not os.path.isdir(parent):
+ os.makedirs(parent, mode=0o750, exist_ok=True)
+ if monotonic and os.path.isfile(Upgrade.ProgressPathNew):
+ try:
+ with open(Upgrade.ProgressPathNew, 'r') as rf:
+ cur = int(json.loads(rf.read()).get('pct', 0))
+ pct = max(pct, cur)
+ except (ValueError, TypeError, json.JSONDecodeError, OSError):
+ pass
+ with open(Upgrade.ProgressPathNew, 'w') as wf:
+ wf.write(json.dumps({'pct': pct}))
+ except (OSError, TypeError, ValueError):
+ pass
+
+ @staticmethod
+ def _upgrade_init_files_and_progress():
+ """Create log/progress files before first stdOut so UI polling never hits cat errors."""
+ try:
+ parent = '/home/cyberpanel'
+ if not os.path.isdir(parent):
+ os.makedirs(parent, mode=0o750, exist_ok=True)
+ with open(Upgrade.LogPathNew, 'a'):
+ pass
+ Upgrade.write_upgrade_progress(0)
+ except (OSError, TypeError, ValueError):
+ pass
+
@staticmethod
def FetchCloudLinuxAlmaVersionVersion():
if os.path.exists('/etc/os-release'):
@@ -447,6 +482,16 @@ class Upgrade:
"%m.%d.%Y_%H-%M-%S") + "] #########################################################################\n"))
WriteToFile.close()
+ try:
+ if 'Upgrade Completed' in message:
+ Upgrade.write_upgrade_progress(100)
+ elif os.path.isfile(Upgrade.LogPathNew):
+ sz = os.path.getsize(Upgrade.LogPathNew)
+ est = min(92, 4 + int(sz / 6000))
+ Upgrade.write_upgrade_progress(est, monotonic=True)
+ except (OSError, TypeError, ValueError):
+ pass
+
if do_exit:
### remove log file path incase its there
@@ -1587,13 +1632,6 @@ $cfg['Servers'][$i]['port'] = '3306';
command = f'/usr/local/lsws/lsphp83/bin/php /usr/local/CyberCP/snappymail_cyberpanel.php'
Upgrade.executioner_silent(command, 'verify certificate', 0)
- try:
- from plogical.snappymail_plugin_utilities import install_and_enable_list_unsubscribe_header_plugin
- if install_and_enable_list_unsubscribe_header_plugin():
- Upgrade.stdOut("SnappyMail list-unsubscribe-header plugin installed and enabled", 0)
- except BaseException as plug_msg:
- Upgrade.stdOut("Warning: list-unsubscribe SnappyMail plugin: " + str(plug_msg), 0)
-
# labsPath = '/usr/local/lscp/cyberpanel/rainloop/data/_data_/_default_/configs/application.ini'
# labsData = """[labs]
@@ -6532,6 +6570,9 @@ slowlog = /var/log/php{version}-fpm-slow.log
Upgrade.SoftUpgrade = 1
branch = branch.split(',')[1]
+ Upgrade._upgrade_init_files_and_progress()
+ Upgrade.write_upgrade_progress(6)
+
# Upgrade.stdOut("Upgrades are currently disabled")
# return 0
@@ -6550,6 +6591,8 @@ slowlog = /var/log/php{version}-fpm-slow.log
Upgrade.stdOut(f"Error getting installed packages: {str(e)}")
Upgrade.installedOutput = ""
+ Upgrade.write_upgrade_progress(12, monotonic=True)
+
# command = 'systemctl stop cpssh'
# Upgrade.executioner(command, 'fix csf if there', 0)
@@ -7151,6 +7194,11 @@ slowlog = /var/log/php{version}-fpm-slow.log
time.sleep(30)
if os.path.exists(Upgrade.LogPathNew):
os.remove(Upgrade.LogPathNew)
+ try:
+ if os.path.isfile(Upgrade.ProgressPathNew):
+ os.remove(Upgrade.ProgressPathNew)
+ except OSError:
+ pass
@staticmethod
def fixApacheConfigurationOld():
diff --git a/public/static/baseTemplate/custom-js/system-status.js b/public/static/baseTemplate/custom-js/system-status.js
index b4cf11a11..4cdc013aa 100644
--- a/public/static/baseTemplate/custom-js/system-status.js
+++ b/public/static/baseTemplate/custom-js/system-status.js
@@ -696,6 +696,12 @@ app.controller('versionManagment', function ($scope, $http, $timeout) {
$scope.updateStarted = false;
$scope.updateFinish = true;
$scope.couldNotConnect = true;
+ var startPct = (typeof response.data.progress !== 'undefined' && isFinite(response.data.progress))
+ ? response.data.progress : 0;
+ var progEl = document.getElementById('upgradeProgressLog');
+ if (progEl) {
+ progEl.innerText = 'Upgrade Progress: ' + startPct + '%';
+ }
getUpgradeStatus();
} else {
$scope.updateError = false;
@@ -740,6 +746,12 @@ app.controller('versionManagment', function ($scope, $http, $timeout) {
function ListInitialDatas(response) {
console.log(response.data.upgradeLog);
+ var pct = (typeof response.data.progress !== 'undefined' && isFinite(response.data.progress))
+ ? response.data.progress : 0;
+ var progEl = document.getElementById('upgradeProgressLog');
+ if (progEl) {
+ progEl.innerText = 'Upgrade Progress: ' + pct + '%';
+ }
if (response.data.upgradeStatus === 1) {
@@ -753,6 +765,9 @@ app.controller('versionManagment', function ($scope, $http, $timeout) {
$scope.updateStarted = true;
$scope.updateFinish = false;
$scope.couldNotConnect = true;
+ if (progEl) {
+ progEl.innerText = 'Upgrade Progress: 100%';
+ }
} else {
$scope.upgradelogBox = false;
diff --git a/static/baseTemplate/custom-js/system-status.js b/static/baseTemplate/custom-js/system-status.js
index b4cf11a11..4cdc013aa 100644
--- a/static/baseTemplate/custom-js/system-status.js
+++ b/static/baseTemplate/custom-js/system-status.js
@@ -696,6 +696,12 @@ app.controller('versionManagment', function ($scope, $http, $timeout) {
$scope.updateStarted = false;
$scope.updateFinish = true;
$scope.couldNotConnect = true;
+ var startPct = (typeof response.data.progress !== 'undefined' && isFinite(response.data.progress))
+ ? response.data.progress : 0;
+ var progEl = document.getElementById('upgradeProgressLog');
+ if (progEl) {
+ progEl.innerText = 'Upgrade Progress: ' + startPct + '%';
+ }
getUpgradeStatus();
} else {
$scope.updateError = false;
@@ -740,6 +746,12 @@ app.controller('versionManagment', function ($scope, $http, $timeout) {
function ListInitialDatas(response) {
console.log(response.data.upgradeLog);
+ var pct = (typeof response.data.progress !== 'undefined' && isFinite(response.data.progress))
+ ? response.data.progress : 0;
+ var progEl = document.getElementById('upgradeProgressLog');
+ if (progEl) {
+ progEl.innerText = 'Upgrade Progress: ' + pct + '%';
+ }
if (response.data.upgradeStatus === 1) {
@@ -753,6 +765,9 @@ app.controller('versionManagment', function ($scope, $http, $timeout) {
$scope.updateStarted = true;
$scope.updateFinish = false;
$scope.couldNotConnect = true;
+ if (progEl) {
+ progEl.innerText = 'Upgrade Progress: 100%';
+ }
} else {
$scope.upgradelogBox = false;