mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2026-02-17 03:56:48 +01:00
MySQL Manager: fix status/processes load, Query Info 'No query', MariaDB-safe parsing, deploy docs
- databases.js: app ref for ctrlreg, cache-buster, error handling, public/static sync - mysqlUtilities: column-name process list (MariaDB), SHOW GLOBAL STATUS safe parse, Query Info 'No query' - mysqlmanager.html: Query Info fallback for NULL - Deploy docs: DEPLOY-BEFORE-PUSH, DEPLOY-MYSQL-MANAGER-TO-SERVER (public/static) - Other: CyberPanelUpgrade, upgrade, websiteFunctions, userManagment, website
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
* Created by usman on 8/6/17.
|
||||
*/
|
||||
|
||||
/* Ensure we register controllers on the CyberCP app (avoids ctrlreg if load order differs) */
|
||||
var app = (typeof window.app !== 'undefined' && window.app) ? window.app : angular.module('CyberCP');
|
||||
|
||||
/* Java script code to create database */
|
||||
app.controller('createDatabase', function ($scope, $http) {
|
||||
@@ -694,7 +696,7 @@ app.controller('Mysqlmanager', function ($scope, $http, $compile, $window, $time
|
||||
|
||||
$scope.cyberPanelLoading = true;
|
||||
|
||||
url = "/dataBases/getMysqlstatus";
|
||||
url = "/dataBases/getMysqlstatus?t=" + (Date.now ? Date.now() : new Date().getTime());
|
||||
|
||||
var data = {};
|
||||
|
||||
@@ -715,6 +717,8 @@ app.controller('Mysqlmanager', function ($scope, $http, $compile, $window, $time
|
||||
try {
|
||||
data = JSON.parse(data);
|
||||
} catch (e) {
|
||||
$scope.uptime = $scope.connections = $scope.Slow_queries = '—';
|
||||
$scope.processes = [];
|
||||
new PNotify({ title: 'Error!', text: 'Invalid response from server.', type: 'error' });
|
||||
return;
|
||||
}
|
||||
@@ -749,7 +753,21 @@ app.controller('Mysqlmanager', function ($scope, $http, $compile, $window, $time
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.cyberPanelLoading = false;
|
||||
var msg = (response.data && response.data.error_message) || (response.statusText || 'Cannot load MySQL status.');
|
||||
$scope.uptime = '—';
|
||||
$scope.connections = '—';
|
||||
$scope.Slow_queries = '—';
|
||||
$scope.processes = [];
|
||||
var msg = 'Cannot load MySQL status.';
|
||||
if (response && response.status) {
|
||||
msg = 'Request failed: ' + response.status + (response.statusText ? ' ' + response.statusText : '');
|
||||
}
|
||||
if (response && response.data) {
|
||||
if (typeof response.data === 'string' && response.data.length < 200) {
|
||||
msg = response.data;
|
||||
} else if (response.data.error_message) {
|
||||
msg = response.data.error_message;
|
||||
}
|
||||
}
|
||||
new PNotify({
|
||||
title: 'Error!',
|
||||
text: msg,
|
||||
|
||||
@@ -644,8 +644,8 @@
|
||||
</td>
|
||||
<td>
|
||||
<span class="info-text"
|
||||
ng-bind="process.info || 'No query'"
|
||||
ng-attr-title="{$ process.info $}"></span>
|
||||
ng-bind="(process.info && process.info !== 'NULL') ? process.info : 'No query'"
|
||||
ng-attr-title="{$ (process.info && process.info !== 'NULL') ? process.info : 'No query' $}"></span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="progress-bar">
|
||||
|
||||
@@ -79,6 +79,7 @@ class UpgradeCyberPanel:
|
||||
Upgrade.CLMigrations()
|
||||
Upgrade.IncBackupMigrations()
|
||||
Upgrade.applyLoginSystemMigrations()
|
||||
Upgrade.homeDirectoryMigrations()
|
||||
Upgrade.s3BackupMigrations()
|
||||
Upgrade.containerMigrations()
|
||||
Upgrade.manageServiceMigrations()
|
||||
|
||||
@@ -531,47 +531,63 @@ password=%s
|
||||
data['status'] = 1
|
||||
|
||||
for items in result:
|
||||
if items[0] == 'Uptime':
|
||||
data['uptime'] = mysqlUtilities.GetTime(items[1])
|
||||
elif items[0] == 'Connections':
|
||||
data['connections'] = items[1]
|
||||
elif items[0] == 'Slow_queries':
|
||||
data['Slow_queries'] = items[1]
|
||||
if not items or len(items) < 2:
|
||||
continue
|
||||
key = (items[0] or '').strip()
|
||||
val = items[1]
|
||||
if key == 'Uptime':
|
||||
try:
|
||||
data['uptime'] = mysqlUtilities.GetTime(val)
|
||||
except (TypeError, ValueError):
|
||||
data['uptime'] = str(val) if val is not None else '0'
|
||||
elif key == 'Connections':
|
||||
data['connections'] = val
|
||||
elif key == 'Slow_queries':
|
||||
data['Slow_queries'] = val
|
||||
|
||||
## Process List
|
||||
|
||||
cursor.execute("show processlist")
|
||||
## Process List (column-name based so it works with any MySQL/MariaDB version)
|
||||
cursor.execute("SHOW FULL PROCESSLIST")
|
||||
if cursor.description:
|
||||
col_names = [col[0].lower() if col[0] else '' for col in cursor.description]
|
||||
else:
|
||||
col_names = []
|
||||
result = cursor.fetchall()
|
||||
|
||||
json_data = "["
|
||||
checker = 0
|
||||
|
||||
for items in result:
|
||||
# SHOW PROCESSLIST: Id, User, Host, db, Command, Time, State, Info [, Progress]
|
||||
if items[3] is None or len(str(items[3])) == 0:
|
||||
for row in result:
|
||||
if col_names:
|
||||
row_dict = dict(zip(col_names, row)) if len(col_names) == len(row) else {}
|
||||
else:
|
||||
row_dict = {}
|
||||
# Support both MySQL and MariaDB column names (Id/id, User/user, db/DB, etc.)
|
||||
def get_col(*keys, default=None):
|
||||
for k in keys:
|
||||
v = row_dict.get(k) if row_dict else None
|
||||
if v is not None and (not isinstance(v, str) or len(str(v).strip()) > 0):
|
||||
return v
|
||||
return default
|
||||
|
||||
database = get_col('db', 'database', default='NULL')
|
||||
if database is None or (isinstance(database, str) and len(database.strip()) == 0):
|
||||
database = 'NULL'
|
||||
else:
|
||||
database = items[3]
|
||||
|
||||
if len(items) > 6 and items[6] is not None and len(str(items[6])) > 0:
|
||||
state = items[6]
|
||||
else:
|
||||
state = get_col('state', default='NULL')
|
||||
if state is None or (isinstance(state, str) and len(str(state).strip()) == 0):
|
||||
state = 'NULL'
|
||||
|
||||
if len(items) > 7 and items[7] is not None and len(str(items[7])) > 0:
|
||||
info = items[7]
|
||||
else:
|
||||
info = 'NULL'
|
||||
info = get_col('info', default=None)
|
||||
if info is None or (isinstance(info, str) and len(str(info).strip()) == 0):
|
||||
info = 'No query'
|
||||
|
||||
dic = {
|
||||
'id': items[0],
|
||||
'user': items[1],
|
||||
'id': get_col('id', default=0),
|
||||
'user': get_col('user', default=''),
|
||||
'database': database,
|
||||
'command': items[4] if len(items) > 4 else '',
|
||||
'time': items[5] if len(items) > 5 else 0,
|
||||
'command': get_col('command', default=''),
|
||||
'time': get_col('time', 'time_ms', default=0),
|
||||
'state': state,
|
||||
'info': info,
|
||||
'progress': items[8] if len(items) > 8 else 0,
|
||||
'progress': get_col('progress', default=0),
|
||||
}
|
||||
|
||||
if checker == 0:
|
||||
|
||||
@@ -2382,6 +2382,50 @@ CREATE TABLE `websiteFunctions_backupsv2` (`id` integer AUTO_INCREMENT NOT NULL
|
||||
except OSError as msg:
|
||||
Upgrade.stdOut(str(msg) + " [applyLoginSystemMigrations]")
|
||||
|
||||
@staticmethod
|
||||
def homeDirectoryMigrations():
|
||||
"""Create home_directories and user_home_mappings tables if missing (Modify Website home directory feature)."""
|
||||
try:
|
||||
connection, cursor = Upgrade.setupConnection('cyberpanel')
|
||||
try:
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS `home_directories` (
|
||||
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
|
||||
`name` varchar(50) NOT NULL UNIQUE,
|
||||
`path` varchar(255) NOT NULL UNIQUE,
|
||||
`is_active` tinyint(1) NOT NULL DEFAULT 1,
|
||||
`is_default` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`max_users` integer NOT NULL DEFAULT 0,
|
||||
`description` longtext,
|
||||
`created_at` datetime(6) NOT NULL,
|
||||
`updated_at` datetime(6) NOT NULL
|
||||
)
|
||||
""")
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS `user_home_mappings` (
|
||||
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
|
||||
`user_id` integer NOT NULL UNIQUE,
|
||||
`home_directory_id` integer NOT NULL,
|
||||
`created_at` datetime(6) NOT NULL,
|
||||
`updated_at` datetime(6) NOT NULL,
|
||||
CONSTRAINT `user_home_mappings_user_id_fk` FOREIGN KEY (`user_id`)
|
||||
REFERENCES `loginSystem_administrator` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `user_home_mappings_home_directory_id_fk` FOREIGN KEY (`home_directory_id`)
|
||||
REFERENCES `home_directories` (`id`) ON DELETE CASCADE
|
||||
)
|
||||
""")
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
connection.close()
|
||||
except Exception:
|
||||
pass
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def s3BackupMigrations():
|
||||
try:
|
||||
@@ -5851,6 +5895,7 @@ slowlog = /var/log/php{version}-fpm-slow.log
|
||||
##
|
||||
|
||||
Upgrade.applyLoginSystemMigrations()
|
||||
Upgrade.homeDirectoryMigrations()
|
||||
|
||||
## Put function here to update custom ACLs
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
* Created by usman on 8/6/17.
|
||||
*/
|
||||
|
||||
/* Ensure we register controllers on the CyberCP app (avoids ctrlreg if load order differs) */
|
||||
var app = (typeof window.app !== 'undefined' && window.app) ? window.app : angular.module('CyberCP');
|
||||
|
||||
/* Java script code to create database */
|
||||
app.controller('createDatabase', function ($scope, $http) {
|
||||
@@ -10,22 +12,72 @@ app.controller('createDatabase', function ($scope, $http) {
|
||||
$(".dbDetails").hide();
|
||||
$(".generatedPasswordDetails").hide();
|
||||
$('#create-database-select').select2();
|
||||
|
||||
// Initialize preview if website is already selected
|
||||
setTimeout(function() {
|
||||
if ($scope.databaseWebsite) {
|
||||
var truncatedName = $scope.getTruncatedWebName($scope.databaseWebsite);
|
||||
$("#domainDatabase").text(truncatedName);
|
||||
$("#domainUsername").text(truncatedName);
|
||||
$(".dbDetails").show();
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
|
||||
// Helper function to get truncated website name
|
||||
$scope.getTruncatedWebName = function(domain) {
|
||||
if (!domain) return '';
|
||||
|
||||
// Remove hyphens and get first part before dot
|
||||
var webName = domain.replace(/-/g, '').split('.')[0];
|
||||
|
||||
// Truncate to 4 characters if longer than 5
|
||||
if (webName.length > 5) {
|
||||
webName = webName.substring(0, 4);
|
||||
}
|
||||
|
||||
return webName;
|
||||
};
|
||||
|
||||
$('#create-database-select').on('select2:select', function (e) {
|
||||
var data = e.params.data;
|
||||
$scope.databaseWebsite = data.text;
|
||||
$(".dbDetails").show();
|
||||
$("#domainDatabase").text(getWebsiteName(data.text));
|
||||
$("#domainUsername").text(getWebsiteName(data.text));
|
||||
|
||||
// Use local truncation function to ensure consistency
|
||||
var truncatedName = $scope.getTruncatedWebName(data.text);
|
||||
$("#domainDatabase").text(truncatedName);
|
||||
$("#domainUsername").text(truncatedName);
|
||||
|
||||
// Apply scope to update Angular bindings
|
||||
$scope.$apply();
|
||||
});
|
||||
|
||||
|
||||
$scope.showDetailsBoxes = function () {
|
||||
$scope.dbDetails = false;
|
||||
}
|
||||
|
||||
// Function called when website selection changes
|
||||
$scope.websiteChanged = function() {
|
||||
if ($scope.databaseWebsite) {
|
||||
$(".dbDetails").show();
|
||||
var truncatedName = $scope.getTruncatedWebName($scope.databaseWebsite);
|
||||
$("#domainDatabase").text(truncatedName);
|
||||
$("#domainUsername").text(truncatedName);
|
||||
}
|
||||
}
|
||||
|
||||
$scope.createDatabaseLoading = true;
|
||||
|
||||
// Watch for changes to databaseWebsite to update preview
|
||||
$scope.$watch('databaseWebsite', function(newValue, oldValue) {
|
||||
if (newValue && newValue !== oldValue) {
|
||||
var truncatedName = $scope.getTruncatedWebName(newValue);
|
||||
$("#domainDatabase").text(truncatedName);
|
||||
$("#domainUsername").text(truncatedName);
|
||||
}
|
||||
});
|
||||
|
||||
$scope.createDatabase = function () {
|
||||
|
||||
@@ -39,14 +91,8 @@ app.controller('createDatabase', function ($scope, $http) {
|
||||
var dbPassword = $scope.dbPassword;
|
||||
var webUserName = "";
|
||||
|
||||
// getting website username
|
||||
|
||||
webUserName = databaseWebsite.replace(/-/g, '');
|
||||
webUserName = webUserName.split(".")[0];
|
||||
|
||||
if (webUserName.length > 5) {
|
||||
webUserName = webUserName.substring(0, 4);
|
||||
}
|
||||
// getting website username - use the same truncation function for consistency
|
||||
webUserName = $scope.getTruncatedWebName(databaseWebsite);
|
||||
|
||||
var url = "/dataBases/submitDBCreation";
|
||||
|
||||
@@ -75,9 +121,15 @@ app.controller('createDatabase', function ($scope, $http) {
|
||||
|
||||
$scope.createDatabaseLoading = true;
|
||||
$scope.dbDetails = false;
|
||||
var successMessage = 'Database successfully created.';
|
||||
if (response.data.dbName && response.data.dbUsername) {
|
||||
successMessage = 'Database successfully created.\n' +
|
||||
'Database Name: ' + response.data.dbName + '\n' +
|
||||
'Database User: ' + response.data.dbUsername;
|
||||
}
|
||||
new PNotify({
|
||||
title: 'Success!',
|
||||
text: 'Database successfully created.',
|
||||
text: successMessage,
|
||||
type: 'success'
|
||||
});
|
||||
} else {
|
||||
@@ -589,8 +641,34 @@ app.controller('phpMyAdmin', function ($scope, $http, $window) {
|
||||
function ListInitialDatas(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
var rUrl = '/phpmyadmin/phpmyadminsignin.php?username=' + response.data.username + '&token=' + response.data.token;
|
||||
$window.location.href = rUrl;
|
||||
//var rUrl = '/phpmyadmin/phpmyadminsignin.php?username=' + response.data.username + '&token=' + response.data.token;
|
||||
//$window.location.href = rUrl;
|
||||
|
||||
var form = document.createElement('form');
|
||||
form.method = 'post';
|
||||
form.action = '/phpmyadmin/phpmyadminsignin.php';
|
||||
|
||||
// Create input elements for username and token
|
||||
var usernameInput = document.createElement('input');
|
||||
usernameInput.type = 'hidden';
|
||||
usernameInput.name = 'username';
|
||||
usernameInput.value = response.data.username;
|
||||
|
||||
var tokenInput = document.createElement('input');
|
||||
tokenInput.type = 'hidden';
|
||||
tokenInput.name = 'token';
|
||||
tokenInput.value = response.data.token;
|
||||
|
||||
// Append input elements to the form
|
||||
form.appendChild(usernameInput);
|
||||
form.appendChild(tokenInput);
|
||||
|
||||
// Append the form to the body
|
||||
document.body.appendChild(form);
|
||||
|
||||
// Submit the form
|
||||
form.submit();
|
||||
|
||||
} else {
|
||||
}
|
||||
|
||||
@@ -603,3 +681,415 @@ app.controller('phpMyAdmin', function ($scope, $http, $window) {
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
app.controller('Mysqlmanager', function ($scope, $http, $compile, $window, $timeout) {
|
||||
$scope.cyberPanelLoading = false;
|
||||
$scope.mysql_status = 'test';
|
||||
$scope.uptime = '—';
|
||||
$scope.connections = '—';
|
||||
$scope.Slow_queries = '—';
|
||||
$scope.processes = [];
|
||||
|
||||
|
||||
$scope.getstatus = function () {
|
||||
|
||||
$scope.cyberPanelLoading = true;
|
||||
|
||||
url = "/dataBases/getMysqlstatus?t=" + (Date.now ? Date.now() : new Date().getTime());
|
||||
|
||||
var data = {};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
$scope.cyberPanelLoading = false;
|
||||
var data = response.data;
|
||||
if (typeof data === 'string') {
|
||||
try {
|
||||
data = JSON.parse(data);
|
||||
} catch (e) {
|
||||
$scope.uptime = $scope.connections = $scope.Slow_queries = '—';
|
||||
$scope.processes = [];
|
||||
new PNotify({ title: 'Error!', text: 'Invalid response from server.', type: 'error' });
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (data && data.status === 1) {
|
||||
$scope.uptime = data.uptime || '—';
|
||||
$scope.connections = data.connections != null ? data.connections : '—';
|
||||
$scope.Slow_queries = data.Slow_queries != null ? data.Slow_queries : '—';
|
||||
try {
|
||||
$scope.processes = typeof data.processes === 'string' ? JSON.parse(data.processes || '[]') : (data.processes || []);
|
||||
} catch (e) {
|
||||
$scope.processes = [];
|
||||
}
|
||||
if (typeof $scope.showStatus === 'function') {
|
||||
$timeout($scope.showStatus, 3000);
|
||||
}
|
||||
|
||||
new PNotify({
|
||||
title: 'Success',
|
||||
text: 'Successfully Fetched',
|
||||
type: 'success'
|
||||
});
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Error!',
|
||||
text: (data && data.error_message) || 'Could not load MySQL status.',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.cyberPanelLoading = false;
|
||||
$scope.uptime = '—';
|
||||
$scope.connections = '—';
|
||||
$scope.Slow_queries = '—';
|
||||
$scope.processes = [];
|
||||
var msg = 'Cannot load MySQL status.';
|
||||
if (response && response.status) {
|
||||
msg = 'Request failed: ' + response.status + (response.statusText ? ' ' + response.statusText : '');
|
||||
}
|
||||
if (response && response.data) {
|
||||
if (typeof response.data === 'string' && response.data.length < 200) {
|
||||
msg = response.data;
|
||||
} else if (response.data.error_message) {
|
||||
msg = response.data.error_message;
|
||||
}
|
||||
}
|
||||
new PNotify({
|
||||
title: 'Error!',
|
||||
text: msg,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$scope.refreshProcesses = function () {
|
||||
var icon = document.querySelector('.refresh-btn i');
|
||||
if (icon) {
|
||||
icon.style.animation = 'spin 1s linear';
|
||||
setTimeout(function () { icon.style.animation = ''; }, 1000);
|
||||
}
|
||||
$scope.getstatus();
|
||||
};
|
||||
|
||||
$scope.getstatus();
|
||||
});
|
||||
|
||||
|
||||
app.controller('OptimizeMysql', function ($scope, $http) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
|
||||
$scope.generateRecommendations = function () {
|
||||
$scope.cyberhosting = false;
|
||||
url = "/dataBases/generateRecommendations";
|
||||
|
||||
var data = {
|
||||
detectedRam: $("#detectedRam").text()
|
||||
};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
$http.post(url, data, config).then(ListInitialData, cantLoadInitialData);
|
||||
|
||||
|
||||
function ListInitialData(response) {
|
||||
$scope.cyberhosting = true;
|
||||
if (response.data.status === 1) {
|
||||
$scope.suggestedContent = response.data.generatedConf;
|
||||
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Error!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialData(response) {
|
||||
$scope.cyberhosting = true;
|
||||
new PNotify({
|
||||
title: 'Error!',
|
||||
text: 'Could not connect to server, please refresh this page.',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
$scope.applyMySQLChanges = function () {
|
||||
$scope.cyberhosting = false;
|
||||
url = "/dataBases/applyMySQLChanges";
|
||||
|
||||
var encodedContent = encodeURIComponent($scope.suggestedContent);
|
||||
|
||||
var data = {
|
||||
suggestedContent: encodedContent
|
||||
};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
$http.post(url, data, config).then(ListInitialData, cantLoadInitialData);
|
||||
|
||||
|
||||
function ListInitialData(response) {
|
||||
$scope.cyberhosting = true;
|
||||
if (response.data.status === 1) {
|
||||
|
||||
new PNotify({
|
||||
title: 'Success',
|
||||
text: 'Changes successfully applied.',
|
||||
type: 'success'
|
||||
});
|
||||
|
||||
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Error!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialData(response) {
|
||||
$scope.cyberhosting = true;
|
||||
new PNotify({
|
||||
title: 'Error!',
|
||||
text: 'Could not connect to server, please refresh this page.',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
$scope.restartMySQL = function () {
|
||||
$scope.cyberPanelLoading = false;
|
||||
|
||||
url = "/dataBases/restartMySQL";
|
||||
|
||||
var data = {};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
new PNotify({
|
||||
title: 'Success',
|
||||
text: 'Successfully Done',
|
||||
type: 'success'
|
||||
});
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Error!',
|
||||
text: response.data.error_message,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialData(response) {
|
||||
$scope.cyberhosting = true;
|
||||
new PNotify({
|
||||
title: 'Error!',
|
||||
text: 'Could not connect to server, please refresh this page.',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
app.controller('mysqlupdate', function ($scope, $http, $timeout) {
|
||||
$scope.cyberPanelLoading = true;
|
||||
$scope.dbLoading = true;
|
||||
$scope.modeSecInstallBox = true;
|
||||
$scope.modsecLoading = true;
|
||||
$scope.failedToStartInallation = true;
|
||||
$scope.couldNotConnect = true;
|
||||
$scope.modSecSuccessfullyInstalled = true;
|
||||
$scope.installationFailed = true;
|
||||
|
||||
$scope.Upgardemysql = function () {
|
||||
$scope.dbLoading = false;
|
||||
$scope.installform = true;
|
||||
$scope.modSecNotifyBox = true;
|
||||
$scope.modeSecInstallBox = false;
|
||||
$scope.modsecLoading = false;
|
||||
$scope.failedToStartInallation = true;
|
||||
$scope.couldNotConnect = true;
|
||||
$scope.modSecSuccessfullyInstalled = true;
|
||||
$scope.installationFailed = true;
|
||||
|
||||
|
||||
url = "/dataBases/upgrademysqlnow";
|
||||
|
||||
var data = {
|
||||
mysqlversion: $scope.version
|
||||
};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
$http.post(url, data, config).then(ListInitialData, cantLoadInitialData);
|
||||
|
||||
|
||||
function ListInitialData(response) {
|
||||
$scope.cyberhosting = true;
|
||||
if (response.data.status === 1) {
|
||||
$scope.modSecNotifyBox = true;
|
||||
$scope.modeSecInstallBox = false;
|
||||
$scope.modsecLoading = false;
|
||||
$scope.failedToStartInallation = true;
|
||||
$scope.couldNotConnect = true;
|
||||
$scope.modSecSuccessfullyInstalled = true;
|
||||
$scope.installationFailed = true;
|
||||
|
||||
$scope.statusfile = response.data.tempStatusPath
|
||||
|
||||
$timeout(getRequestStatus, 1000);
|
||||
|
||||
} else {
|
||||
$scope.errorMessage = response.data.error_message;
|
||||
|
||||
$scope.modSecNotifyBox = false;
|
||||
$scope.modeSecInstallBox = true;
|
||||
$scope.modsecLoading = true;
|
||||
$scope.failedToStartInallation = false;
|
||||
$scope.couldNotConnect = true;
|
||||
$scope.modSecSuccessfullyInstalled = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialData(response) {
|
||||
$scope.cyberhosting = true;
|
||||
new PNotify({
|
||||
title: 'Error!',
|
||||
text: 'Could not connect to server, please refresh this page.',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getRequestStatus() {
|
||||
|
||||
$scope.modSecNotifyBox = true;
|
||||
$scope.modeSecInstallBox = false;
|
||||
$scope.modsecLoading = false;
|
||||
$scope.failedToStartInallation = true;
|
||||
$scope.couldNotConnect = true;
|
||||
$scope.modSecSuccessfullyInstalled = true;
|
||||
$scope.installationFailed = true;
|
||||
|
||||
url = "/dataBases/upgrademysqlstatus";
|
||||
|
||||
var data = {
|
||||
statusfile: $scope.statusfile
|
||||
};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
|
||||
|
||||
if (response.data.abort === 0) {
|
||||
|
||||
$scope.modSecNotifyBox = true;
|
||||
$scope.modeSecInstallBox = false;
|
||||
$scope.modsecLoading = false;
|
||||
$scope.failedToStartInallation = true;
|
||||
$scope.couldNotConnect = true;
|
||||
$scope.modSecSuccessfullyInstalled = true;
|
||||
$scope.installationFailed = true;
|
||||
|
||||
$scope.requestData = response.data.requestStatus;
|
||||
$timeout(getRequestStatus, 1000);
|
||||
} else {
|
||||
// Notifications
|
||||
$timeout.cancel();
|
||||
$scope.modSecNotifyBox = false;
|
||||
$scope.modeSecInstallBox = false;
|
||||
$scope.modsecLoading = true;
|
||||
$scope.failedToStartInallation = true;
|
||||
$scope.couldNotConnect = true;
|
||||
|
||||
$scope.requestData = response.data.requestStatus;
|
||||
|
||||
if (response.data.installed === 0) {
|
||||
$scope.installationFailed = false;
|
||||
$scope.errorMessage = response.data.error_message;
|
||||
} else {
|
||||
$scope.modSecSuccessfullyInstalled = false;
|
||||
$timeout(function () {
|
||||
$window.location.reload();
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
|
||||
$scope.modSecNotifyBox = false;
|
||||
$scope.modeSecInstallBox = false;
|
||||
$scope.modsecLoading = true;
|
||||
$scope.failedToStartInallation = true;
|
||||
$scope.couldNotConnect = false;
|
||||
$scope.modSecSuccessfullyInstalled = true;
|
||||
$scope.installationFailed = true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
@@ -10765,7 +10765,7 @@ app.controller('modifyWebsitesController', ['$scope', '$http', function ($scope,
|
||||
|
||||
// Load home directories on page load
|
||||
$scope.loadHomeDirectories = function() {
|
||||
$http.post('/userManagement/getUserHomeDirectories/', {})
|
||||
$http.post('/users/getUserHomeDirectories', {})
|
||||
.then(function(response) {
|
||||
if (response.data.status === 1) {
|
||||
$scope.homeDirectories = response.data.directories;
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
* Created by usman on 8/6/17.
|
||||
*/
|
||||
|
||||
/* Ensure we register controllers on the CyberCP app (avoids ctrlreg if load order differs) */
|
||||
var app = (typeof window.app !== 'undefined' && window.app) ? window.app : angular.module('CyberCP');
|
||||
|
||||
/* Java script code to create database */
|
||||
app.controller('createDatabase', function ($scope, $http) {
|
||||
@@ -683,14 +685,18 @@ app.controller('phpMyAdmin', function ($scope, $http, $window) {
|
||||
|
||||
app.controller('Mysqlmanager', function ($scope, $http, $compile, $window, $timeout) {
|
||||
$scope.cyberPanelLoading = false;
|
||||
$scope.mysql_status = 'test'
|
||||
$scope.mysql_status = 'test';
|
||||
$scope.uptime = '—';
|
||||
$scope.connections = '—';
|
||||
$scope.Slow_queries = '—';
|
||||
$scope.processes = [];
|
||||
|
||||
|
||||
$scope.getstatus = function () {
|
||||
|
||||
$scope.cyberPanelLoading = true;
|
||||
|
||||
url = "/dataBases/getMysqlstatus";
|
||||
url = "/dataBases/getMysqlstatus?t=" + (Date.now ? Date.now() : new Date().getTime());
|
||||
|
||||
var data = {};
|
||||
|
||||
@@ -706,12 +712,29 @@ app.controller('Mysqlmanager', function ($scope, $http, $compile, $window, $time
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
$scope.cyberPanelLoading = false;
|
||||
if (response.data.status === 1) {
|
||||
$scope.uptime = response.data.uptime;
|
||||
$scope.connections = response.data.connections;
|
||||
$scope.Slow_queries = response.data.Slow_queries;
|
||||
$scope.processes = JSON.parse(response.data.processes);
|
||||
$timeout($scope.showStatus, 3000);
|
||||
var data = response.data;
|
||||
if (typeof data === 'string') {
|
||||
try {
|
||||
data = JSON.parse(data);
|
||||
} catch (e) {
|
||||
$scope.uptime = $scope.connections = $scope.Slow_queries = '—';
|
||||
$scope.processes = [];
|
||||
new PNotify({ title: 'Error!', text: 'Invalid response from server.', type: 'error' });
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (data && data.status === 1) {
|
||||
$scope.uptime = data.uptime || '—';
|
||||
$scope.connections = data.connections != null ? data.connections : '—';
|
||||
$scope.Slow_queries = data.Slow_queries != null ? data.Slow_queries : '—';
|
||||
try {
|
||||
$scope.processes = typeof data.processes === 'string' ? JSON.parse(data.processes || '[]') : (data.processes || []);
|
||||
} catch (e) {
|
||||
$scope.processes = [];
|
||||
}
|
||||
if (typeof $scope.showStatus === 'function') {
|
||||
$timeout($scope.showStatus, 3000);
|
||||
}
|
||||
|
||||
new PNotify({
|
||||
title: 'Success',
|
||||
@@ -721,7 +744,7 @@ app.controller('Mysqlmanager', function ($scope, $http, $compile, $window, $time
|
||||
} else {
|
||||
new PNotify({
|
||||
title: 'Error!',
|
||||
text: response.data.error_message,
|
||||
text: (data && data.error_message) || 'Could not load MySQL status.',
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
@@ -730,15 +753,39 @@ app.controller('Mysqlmanager', function ($scope, $http, $compile, $window, $time
|
||||
|
||||
function cantLoadInitialDatas(response) {
|
||||
$scope.cyberPanelLoading = false;
|
||||
$scope.uptime = '—';
|
||||
$scope.connections = '—';
|
||||
$scope.Slow_queries = '—';
|
||||
$scope.processes = [];
|
||||
var msg = 'Cannot load MySQL status.';
|
||||
if (response && response.status) {
|
||||
msg = 'Request failed: ' + response.status + (response.statusText ? ' ' + response.statusText : '');
|
||||
}
|
||||
if (response && response.data) {
|
||||
if (typeof response.data === 'string' && response.data.length < 200) {
|
||||
msg = response.data;
|
||||
} else if (response.data.error_message) {
|
||||
msg = response.data.error_message;
|
||||
}
|
||||
}
|
||||
new PNotify({
|
||||
title: 'Error!',
|
||||
text: "cannot load",
|
||||
text: msg,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$scope.refreshProcesses = function () {
|
||||
var icon = document.querySelector('.refresh-btn i');
|
||||
if (icon) {
|
||||
icon.style.animation = 'spin 1s linear';
|
||||
setTimeout(function () { icon.style.animation = ''; }, 1000);
|
||||
}
|
||||
$scope.getstatus();
|
||||
};
|
||||
|
||||
$scope.getstatus();
|
||||
});
|
||||
|
||||
|
||||
26
to-do/DEPLOY-BEFORE-PUSH-V2.5.5-DEV.md
Normal file
26
to-do/DEPLOY-BEFORE-PUSH-V2.5.5-DEV.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Deploy Locally Before Push (v2.5.5-dev)
|
||||
|
||||
## Rule
|
||||
**Always deploy to the local CyberPanel installation before pushing to v2.5.5-dev.**
|
||||
|
||||
When deploying and pushing changes:
|
||||
|
||||
1. **First: Deploy locally**
|
||||
Copy all modified/relevant files from the repo to `/usr/local/CyberCP`, preserving directory structure.
|
||||
|
||||
2. **Then: Commit and push**
|
||||
Stage the same files, commit (author: `master3395`), and push to `origin v2.5.5-dev`.
|
||||
|
||||
## Order
|
||||
1. Deploy → 2. Commit → 3. Push
|
||||
|
||||
Never push to v2.5.5-dev without deploying to `/usr/local/CyberCP` first.
|
||||
|
||||
## Example
|
||||
```bash
|
||||
# 1. Deploy
|
||||
cp /home/cyberpanel-repo/path/to/file /usr/local/CyberCP/path/to/
|
||||
|
||||
# 2. Commit and push
|
||||
cd /home/cyberpanel-repo && git add ... && git commit -m "..." --author="master3395 <master3395@users.noreply.github.com>" && git push origin v2.5.5-dev
|
||||
```
|
||||
53
to-do/DEPLOY-MYSQL-MANAGER-TO-SERVER.md
Normal file
53
to-do/DEPLOY-MYSQL-MANAGER-TO-SERVER.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Deploy MySQL Manager fixes to the server (e.g. 207.180.193.210)
|
||||
|
||||
## Why you still see no data
|
||||
|
||||
- The URL **https://207.180.193.210:2087** is the **remote server** (or your server’s public IP). It is **not** “localhost.”
|
||||
- Our earlier deploy commands ran on the machine where the repo lives. If that machine is **not** the one serving 207.180.193.210, then the panel you open in the browser is still running the **old** code and old `databases.js`.
|
||||
- Seeing **`{$ Slow_queries $}`** (literal text) and empty processes means the **Mysqlmanager** controller or the updated JS is not running on the server that serves that URL.
|
||||
|
||||
## Fix: run the deploy on the server that serves 207.180.193.210
|
||||
|
||||
You must copy the updated files into CyberPanel **on the same machine** that serves https://207.180.193.210:2087 (i.e. where `/usr/local/CyberCP` is used by the panel).
|
||||
|
||||
### Option A – You have the repo on that server (e.g. at `/home/cyberpanel-repo`)
|
||||
|
||||
SSH to **207.180.193.210** (or the host that serves that IP) and run:
|
||||
|
||||
```bash
|
||||
# Path to repo on THAT server (change if different)
|
||||
REPO=/home/cyberpanel-repo
|
||||
|
||||
cp "$REPO/plogical/mysqlUtilities.py" /usr/local/CyberCP/plogical/
|
||||
cp "$REPO/databases/views.py" /usr/local/CyberCP/databases/
|
||||
cp "$REPO/databases/static/databases/databases.js" /usr/local/CyberCP/databases/static/databases/
|
||||
cp "$REPO/static/databases/databases.js" /usr/local/CyberCP/static/databases/
|
||||
# LiteSpeed serves /static/ from public/static/ – must deploy here or the browser gets the old file
|
||||
mkdir -p /usr/local/CyberCP/public/static/databases
|
||||
cp "$REPO/static/databases/databases.js" /usr/local/CyberCP/public/static/databases/
|
||||
|
||||
# Restart panel so changes are used
|
||||
systemctl restart lscpd
|
||||
|
||||
echo "MySQL Manager deploy done. Hard-refresh the MySQL Manager page (Ctrl+Shift+R)."
|
||||
```
|
||||
|
||||
### Option B – Repo is only on another machine (e.g. your dev box)
|
||||
|
||||
1. Copy the **four files** from the machine that has the repo to **207.180.193.210** (e.g. with `scp` or `rsync`):
|
||||
- `plogical/mysqlUtilities.py`
|
||||
- `databases/views.py`
|
||||
- `databases/static/databases/databases.js`
|
||||
- `static/databases/databases.js`
|
||||
|
||||
2. On **207.180.193.210**, run the same `cp` commands as in Option A, using the paths where you put those files instead of `$REPO`.
|
||||
|
||||
3. Restart the panel:
|
||||
`systemctl restart lscpd`
|
||||
|
||||
### After deploy
|
||||
|
||||
- Open **https://207.180.193.210:2087/dataBases/MysqlManager**
|
||||
- Do a **hard refresh**: **Ctrl+Shift+R** (or Cmd+Shift+R on Mac) so the browser doesn’t use cached `databases.js`.
|
||||
|
||||
If you still see no data, open the browser **Developer Tools (F12) → Console** and note any red errors (e.g. `ctrlreg` or 404 for `databases.js`), then share that message.
|
||||
@@ -169,7 +169,7 @@ def getHomeDirectoryStats(request):
|
||||
return JsonResponse({'status': 0, 'error_message': str(e)})
|
||||
|
||||
def getUserHomeDirectories(request):
|
||||
"""Get available home directories for user creation"""
|
||||
"""Get available home directories for user creation. Returns empty list if tables do not exist."""
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
@@ -177,7 +177,7 @@ def getUserHomeDirectories(request):
|
||||
if currentACL['admin'] != 1 and currentACL['createNewUser'] != 1:
|
||||
return JsonResponse({'status': 0, 'error_message': 'Unauthorized access'})
|
||||
|
||||
# Get active home directories
|
||||
# Get active home directories (tables home_directories / user_home_mappings may not exist yet)
|
||||
home_dirs = HomeDirectory.objects.filter(is_active=True).order_by('name')
|
||||
|
||||
directories = []
|
||||
@@ -196,7 +196,8 @@ def getUserHomeDirectories(request):
|
||||
|
||||
except Exception as e:
|
||||
logging.CyberCPLogFileWriter.writeToFile(f"Error getting user home directories: {str(e)}")
|
||||
return JsonResponse({'status': 0, 'error_message': str(e)})
|
||||
# If tables don't exist (e.g. user_home_mappings), return empty list so Modify Website still works
|
||||
return JsonResponse({'status': 1, 'directories': []})
|
||||
|
||||
def migrateUser(request):
|
||||
"""Migrate user to different home directory"""
|
||||
|
||||
@@ -95,7 +95,7 @@ function loadUsers() {
|
||||
|
||||
function loadHomeDirectories() {
|
||||
$.ajax({
|
||||
url: '/userManagement/getUserHomeDirectories/',
|
||||
url: '/users/getUserHomeDirectories',
|
||||
type: 'POST',
|
||||
data: JSON.stringify({}),
|
||||
contentType: 'application/json',
|
||||
|
||||
@@ -3592,10 +3592,14 @@ context /cyberpanel_suspension_page.html {
|
||||
currentPack = modifyWeb.package.packageName
|
||||
owner = modifyWeb.admin.userName
|
||||
|
||||
# Get current home directory information
|
||||
from userManagment.homeDirectoryUtils import HomeDirectoryUtils
|
||||
current_home = HomeDirectoryUtils.getUserHomeDirectoryObject(owner)
|
||||
currentHomeDirectory = current_home.name if current_home else 'Default'
|
||||
# Get current home directory information (optional: tables may not exist yet)
|
||||
currentHomeDirectory = 'Default'
|
||||
try:
|
||||
from userManagment.homeDirectoryUtils import HomeDirectoryUtils
|
||||
current_home = HomeDirectoryUtils.getUserHomeDirectoryObject(owner)
|
||||
currentHomeDirectory = current_home.name if current_home else 'Default'
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
data_ret = {'status': 1, 'modifyStatus': 1, 'error_message': "None", "adminEmail": email,
|
||||
"packages": json_data, "current_pack": currentPack, "adminNames": admin_data,
|
||||
|
||||
Reference in New Issue
Block a user