push changes

This commit is contained in:
Michael Ramsey
2019-10-08 10:53:02 -04:00
parent 0695e9c9d0
commit bd71b39d31
1802 changed files with 170876 additions and 50904 deletions

View File

View File

@@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib import admin
# Register your models here.

8
containerization/apps.py Normal file
View File

@@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.apps import AppConfig
class ContainerizationConfig(AppConfig):
name = 'containerization'

View File

@@ -0,0 +1,125 @@
#!/usr/local/CyberCP/bin/python2
import sys
sys.path.append('/usr/local/CyberCP')
import plogical.CyberCPLogFileWriter as logging
import argparse
from plogical.mailUtilities import mailUtilities
from serverStatus.serverStatusUtil import ServerStatusUtil
class Container:
packages = ['talksho']
users = ['5001']
@staticmethod
def listAll():
try:
counter = 0
length = len(Container.users)
for items in Container.users:
if (counter + 1) == length:
print items + ' ' + Container.packages[counter]
else:
print items + ' ' + Container.packages[counter] + ' '
counter = counter + 1
except BaseException, msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg))
@staticmethod
def listPackages():
try:
counter = 0
length = len(Container.users)
for items in Container.packages:
if (counter + 1) == length:
print items
else:
print items + '\n'
counter = counter + 1
except BaseException, msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg))
@staticmethod
def userIDPackage(user):
try:
counter = 0
for items in Container.users:
if items == user:
print Container.packages[counter]
return
counter = counter + 1
except BaseException, msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg))
@staticmethod
def packageForUser(package):
try:
counter = 0
for items in Container.packages:
if items == package:
print Container.users[counter]
return
counter = counter + 1
except BaseException, msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg))
@staticmethod
def submitContainerInstall():
try:
mailUtilities.checkHome()
statusFile = open(ServerStatusUtil.lswsInstallStatusPath, 'w')
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,
"Starting Packages Installation..\n", 1)
command = 'sudo yum install -y libcgroup-tools'
ServerStatusUtil.executioner(command, statusFile)
command = 'sudo systemctl enable cgconfig'
ServerStatusUtil.executioner(command, statusFile)
command = 'sudo systemctl enable cgred'
ServerStatusUtil.executioner(command, statusFile)
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,
"Packages successfully installed.[200]\n", 1)
except BaseException, msg:
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, str(msg) + ' [404].', 1)
def main():
parser = argparse.ArgumentParser(description='CyberPanel Container Manager')
parser.add_argument('--userid', help='User ID')
parser.add_argument('--package', help='Package')
parser.add_argument('--function', help='Function')
parser.add_argument('--list-all', help='List all users/packages.', action='store_true')
parser.add_argument('--list-packages', help='List all packages.', action='store_true')
args = vars(parser.parse_args())
if args['userid']:
Container.userIDPackage(args['userid'])
elif args['package']:
Container.packageForUser(args['package'])
elif args['list_all']:
Container.listAll()
elif args['list_packages']:
Container.listPackages()
elif args['list_packages']:
Container.listPackages()
elif args["function"] == "submitContainerInstall":
Container.submitContainerInstall()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,179 @@
from django.shortcuts import render
from plogical.processUtilities import ProcessUtilities
import threading as multi
from plogical.acl import ACLManager
import plogical.CyberCPLogFileWriter as logging
from serverStatus.serverStatusUtil import ServerStatusUtil
import os, stat
class ContainerManager(multi.Thread):
defaultConf = """group {groupName}{
cpu {
cpu.cfs_quota_us = {cfs_quota_us};
cpu.cfs_period_us = {cfs_period_us};
}
memory {
memory.limit_in_bytes = {memory}m;
}
blkio {
blkio.throttle.read_bps_device = "{major}:{minor} {io}";
blkio.throttle.write_bps_device = "{major}:{minor} {io}";
blkio.throttle.read_iops_device = "{major}:{minor} {iops}";
blkio.throttle.write_iops_device = "{major}:{minor} {iops}";
}
net_cls
{
net_cls.classid = 0x10{net_cls};
}
}"""
def __init__(self, request=None, templateName=None, function=None, data=None):
multi.Thread.__init__(self)
self.request = request
self.templateName = templateName
self.function = function
self.data = data
def run(self):
try:
if self.function == 'submitContainerInstall':
self.submitContainerInstall()
elif self.function == 'addTrafficController':
self.addTrafficController()
elif self.function == 'removeLimits':
self.removeLimits()
except BaseException, msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg) + ' [ContainerManager.run]')
@staticmethod
def fetchHexValue(count):
hexValue = format(count, '02x')
if len(hexValue) == 1:
return '000' + hexValue
elif len(hexValue) == 2:
return '00' + hexValue
elif len(hexValue) == 3:
return '0' + hexValue
elif len(hexValue) == 3:
return hexValue
@staticmethod
def prepConf(groupName, cfs_quota_us, cfs_period_us, memory, io, iops, net_cls):
try:
dev = os.stat('/')[stat.ST_DEV]
major = str(os.major(dev))
minor = str(0)
finalIO = str(int(io) * 1024 * 1024)
ioConf = ContainerManager.defaultConf.replace('{groupName}', groupName)
ioConf = ioConf.replace('{cfs_quota_us}', cfs_quota_us)
ioConf = ioConf.replace('{cfs_period_us}', cfs_period_us)
ioConf = ioConf.replace('{memory}', memory)
ioConf = ioConf.replace('{major}', major)
ioConf = ioConf.replace('{minor}', minor)
ioConf = ioConf.replace('{io}', finalIO)
ioConf = ioConf.replace('{iops}', str(iops))
ioConf = ioConf.replace('{net_cls}', str(net_cls))
return ioConf
except BaseException, msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg))
return 0
def renderC(self):
userID = self.request.session['userID']
currentACL = ACLManager.loadedACL(userID)
if currentACL['admin'] == 1:
pass
else:
return ACLManager.loadError()
data = {}
data['OLS'] = 0
data['notInstalled'] = 0
if ProcessUtilities.decideServer() == ProcessUtilities.OLS:
data['OLS'] = 1
data['notInstalled'] = 0
return render(self.request, 'containerization/notAvailable.html', data)
elif not ProcessUtilities.containerCheck():
data['OLS'] = 0
data['notInstalled'] = 1
return render(self.request, 'containerization/notAvailable.html', data)
else:
if self.data == None:
self.data = {}
self.data['OLS'] = 0
self.data['notInstalled'] = 0
return render(self.request, self.templateName, self.data)
def submitContainerInstall(self):
try:
userID = self.request.session['userID']
currentACL = ACLManager.loadedACL(userID)
if currentACL['admin'] == 1:
pass
else:
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,
'Not authorized to install container packages. [404].',
1)
return 0
execPath = "/usr/local/CyberCP/bin/python2 /usr/local/CyberCP/containerization/container.py"
execPath = execPath + " --function submitContainerInstall"
ProcessUtilities.outputExecutioner(execPath)
except BaseException, msg:
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, str(msg) + ' [404].', 1)
def restartServices(self):
command = 'sudo systemctl restart cgconfig'
ProcessUtilities.executioner(command)
command = 'sudo systemctl restart cgred'
ProcessUtilities.executioner(command)
def addTrafficController(self):
command = 'sudo tc qdisc add dev eth0 root handle 10: htb default 1000'
#logging.CyberCPLogFileWriter.writeToFile(command)
ProcessUtilities.executioner(command)
try:
command = 'sudo tc class del dev eth0 classid 10:' + str(self.data['classID'])
# logging.CyberCPLogFileWriter.writeToFile(command)
ProcessUtilities.executioner(command)
except:
pass
command = 'sudo tc class add dev eth0 parent 10: classid 10:1000 htb rate 100mbit'
#logging.CyberCPLogFileWriter.writeToFile(command)
ProcessUtilities.executioner(command)
command = 'sudo tc class add dev eth0 parent 10: classid 10:' + str(self.data['classID']) + ' htb rate ' + str(self.data['rateLimit'])
#logging.CyberCPLogFileWriter.writeToFile(command)
ProcessUtilities.executioner(command)
#if str(self.data['classID']) == '1':
# command = 'sudo tc filter add dev eth0 parent 10: protocol ip prio 10 handle 1: cgroup'
#else:
# command = 'sudo tc filter add dev eth0 parent 10:' + str(
# self.data['classID']) + ' protocol ip prio 10 handle 1: cgroup'
command = 'sudo tc filter add dev eth0 parent 10: protocol ip prio 10 handle 1: cgroup'
#logging.CyberCPLogFileWriter.writeToFile(command)
ProcessUtilities.executioner(command)
self.restartServices()
def removeLimits(self):
command = 'sudo tc class del dev eth0 classid 10:' + str(self.data['classID'])
#logging.CyberCPLogFileWriter.writeToFile(command)
ProcessUtilities.executioner(command)
self.restartServices()

View File

View File

@@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
from websiteFunctions.models import Websites
# Create your models here.
class ContainerLimits(models.Model):
owner = models.ForeignKey(Websites, on_delete=models.CASCADE)
cpuPers = models.CharField(max_length=10)
IO = models.CharField(max_length=10)
IOPS = models.CharField(max_length=10)
memory = models.CharField(max_length=10)
networkSpeed = models.CharField(max_length=10)
networkHexValue = models.CharField(max_length=10)
enforce = models.IntegerField(default=0)

View File

@@ -0,0 +1,649 @@
app.controller('installContainer', function ($scope, $http, $timeout, $window) {
$scope.installDockerStatus = true;
$scope.installBoxGen = true;
$scope.dockerInstallBTN = false;
$scope.submitContainerInstall = function () {
$scope.installDockerStatus = false;
$scope.installBoxGen = true;
$scope.dockerInstallBTN = true;
url = "/container/submitContainerInstall";
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) {
$scope.installBoxGen = false;
getRequestStatus();
}
else {
new PNotify({
title: 'Operation Failed!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialDatas(response) {
$scope.cyberPanelLoading = true;
new PNotify({
title: 'Operation Failed!',
text: 'Could not connect to server, please refresh this page',
type: 'error'
});
}
};
function getRequestStatus() {
$scope.cyberPanelLoading = false;
url = "/serverstatus/switchTOLSWSStatus";
var data = {};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
if (response.data.abort === 0) {
$scope.requestData = response.data.requestStatus;
$timeout(getRequestStatus, 1000);
}
else {
// Notifications
$scope.cyberPanelLoading = true;
$timeout.cancel();
$scope.requestData = response.data.requestStatus;
if (response.data.installed === 1) {
$timeout(function () {
$window.location.reload();
}, 3000);
}
}
}
function cantLoadInitialDatas(response) {
$scope.cyberPanelLoading = true;
new PNotify({
title: 'Operation Failed!',
text: 'Could not connect to server, please refresh this page',
type: 'error'
});
}
}
});
app.controller('websiteContainerLimit', function ($scope, $http, $timeout, $window) {
// Get CPU Usage of User
var cpu = [];
var dataset;
var totalPoints = 100;
var updateInterval = 1000;
var now = new Date().getTime();
var options = {
series: {
lines: {
lineWidth: 1.2
},
bars: {
align: "center",
fillColor: {colors: [{opacity: 1}, {opacity: 1}]},
barWidth: 500,
lineWidth: 1
}
},
xaxis: {
mode: "time",
tickSize: [5, "second"],
tickFormatter: function (v, axis) {
var date = new Date(v);
if (date.getSeconds() % 20 == 0) {
var hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
var minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
var seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
return hours + ":" + minutes + ":" + seconds;
} else {
return "";
}
},
axisLabel: "Time",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 10
},
yaxes: [
{
min: 0,
max: 100,
tickSize: 5,
tickFormatter: function (v, axis) {
if (v % 10 == 0) {
return v + "%";
} else {
return "";
}
},
axisLabel: "CPU loading",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 6
}, {
max: 5120,
position: "right",
axisLabel: "Disk",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 6
}
],
legend: {
noColumns: 0,
position: "nw"
},
grid: {
backgroundColor: {colors: ["#ffffff", "#EDF5FF"]}
}
};
function initData() {
for (var i = 0; i < totalPoints; i++) {
var temp = [now += updateInterval, 0];
cpu.push(temp);
}
}
function GetData() {
var data = {
domain: $("#domain").text()
};
$.ajaxSetup({cache: false});
$.ajax({
url: "/container/getUsageData",
dataType: 'json',
success: update,
type: "POST",
headers: { 'X-CSRFToken': getCookie('csrftoken') },
contentType: "application/json",
data: JSON.stringify(data), // Our valid JSON string
error: function () {
setTimeout(GetData, updateInterval);
}
});
}
var temp;
function update(_data) {
cpu.shift();
now += updateInterval;
temp = [now, _data.cpu];
cpu.push(temp);
dataset = [
{label: "CPU:" + _data.cpu + "%", data: cpu, lines: {fill: true, lineWidth: 1.2}, color: "#00FF00"}
];
$.plot($("#flot-placeholder1"), dataset, options);
setTimeout(GetData, updateInterval);
}
// Memory Usage of User
var memory = [];
var datasetMemory;
var totalPointsMemory = 100;
var updateIntervalMemory = 1000;
var nowMemory = new Date().getTime();
var optionsMemory = {
series: {
lines: {
lineWidth: 1.2
},
bars: {
align: "center",
fillColor: {colors: [{opacity: 1}, {opacity: 1}]},
barWidth: 500,
lineWidth: 1
}
},
xaxis: {
mode: "time",
tickSize: [5, "second"],
tickFormatter: function (v, axis) {
var date = new Date(v);
if (date.getSeconds() % 20 == 0) {
var hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
var minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
var seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
return hours + ":" + minutes + ":" + seconds;
} else {
return "";
}
},
axisLabel: "Time",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 10
},
yaxes: [
{
min: 0,
max: $scope.memory,
tickSize: 5,
tickFormatter: function (v, axis) {
if (v % 10 == 0) {
return v + "MB";
} else {
return "";
}
},
axisLabel: "CPU loading",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 6
}, {
max: 5120,
position: "right",
axisLabel: "Disk",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 6
}
],
legend: {
noColumns: 0,
position: "nw"
},
grid: {
backgroundColor: {colors: ["#ffffff", "#EDF5FF"]}
}
};
function initDataMemory() {
for (var i = 0; i < totalPointsMemory; i++) {
var temp = [nowMemory += updateIntervalMemory, 0];
memory.push(temp);
}
}
function GetDataMemory() {
var data = {
domain: $("#domain").text(),
type: 'memory'
};
$.ajaxSetup({cache: false});
$.ajax({
url: "/container/getUsageData",
dataType: 'json',
headers: { 'X-CSRFToken': getCookie('csrftoken') },
success: updateMemory,
type: "POST",
contentType: "application/json",
data: JSON.stringify(data), // Our valid JSON string
error: function () {
setTimeout(GetDataMemory, updateIntervalMemory);
}
});
}
var tempMemory;
function updateMemory(_data) {
memory.shift();
nowMemory += updateIntervalMemory;
tempMemory = [nowMemory, _data.memory];
memory.push(tempMemory);
datasetMemory = [
{
label: "Memory:" + _data.memory + "MB",
data: memory,
lines: {fill: true, lineWidth: 1.2},
color: "#00FF00"
}
];
$.plot($("#memoryUsage"), datasetMemory, optionsMemory);
setTimeout(GetDataMemory, updateIntervalMemory);
}
// Disk Usage
var readRate = [], writeRate = [];
var datasetDisk;
var totalPointsDisk = 100;
var updateIntervalDisk = 5000;
var now = new Date().getTime();
var optionsDisk = {
series: {
lines: {
lineWidth: 1.2
},
bars: {
align: "center",
fillColor: {colors: [{opacity: 1}, {opacity: 1}]},
barWidth: 500,
lineWidth: 1
}
},
xaxis: {
mode: "time",
tickSize: [30, "second"],
tickFormatter: function (v, axis) {
var date = new Date(v);
if (date.getSeconds() % 20 == 0) {
var hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
var minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
var seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
return hours + ":" + minutes + ":" + seconds;
} else {
return "";
}
},
axisLabel: "Time",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 10
},
yaxes: [
{
min: 0,
max: $scope.networkSpeed,
tickSize: 5,
tickFormatter: function (v, axis) {
if (v % 10 == 0) {
return v + "mb/sec";
} else {
return "";
}
},
axisLabel: "CPU loading",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 6
}, {
max: 5120,
position: "right",
axisLabel: "Disk",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 6
}
],
legend: {
noColumns: 0,
position: "nw"
},
grid: {
backgroundColor: {colors: ["#ffffff", "#EDF5FF"]}
}
};
function initDataDisk() {
for (var i = 0; i < totalPointsDisk; i++) {
var temp = [now += updateIntervalDisk, 0];
readRate.push(temp);
writeRate.push(temp);
}
}
function GetDataDisk() {
var data = {
domain: $("#domain").text(),
type: 'io'
};
$.ajaxSetup({cache: false});
$.ajax({
url: "/container/getUsageData",
dataType: 'json',
headers: { 'X-CSRFToken': getCookie('csrftoken') },
success: updateDisk,
type: "POST",
contentType: "application/json",
data: JSON.stringify(data), // Our valid JSON string
error: function () {
setTimeout(GetDataMemory, updateIntervalMemory);
}
});
}
var tempDisk;
function updateDisk(_data) {
readRate.shift();
writeRate.shift();
now += updateIntervalDisk;
tempDisk = [now, _data.readRate];
readRate.push(tempDisk);
tempDisk = [now, _data.readRate];
writeRate.push(tempDisk);
datasetDisk = [
{label: "Read IO/s " + _data.readRate + " mb/s ", data: readRate, lines: {fill: true, lineWidth: 1.2}, color: "#00FF00"},
{label: "Write IO/s " + _data.writeRate + " mb/s ", data: writeRate, lines: {lineWidth: 1.2}, color: "#FF0000"}
];
$.plot($("#diskUsage"), datasetDisk, optionsDisk);
setTimeout(GetDataDisk, updateIntervalDisk);
}
$(document).ready(function () {
initDataDisk();
datasetDisk = [
{label: "Read IO/s: ", data: readRate, lines: {fill: true, lineWidth: 1.2}, color: "#00FF00"},
{label: "Write IO/s: ", data: writeRate, color: "#0044FF", bars: {show: true}, yaxis: 2}
];
$.plot($("#diskUsage"), datasetDisk, optionsDisk);
setTimeout(GetDataDisk, updateIntervalDisk);
});
////
$scope.cyberPanelLoading = true;
$scope.limitsInfoBox = true;
$scope.fetchWebsiteLimits = function () {
$scope.cyberPanelLoading = false;
url = "/container/fetchWebsiteLimits";
var data = {
'domain': $("#domain").text()
};
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) {
$scope.cpuPers = response.data.cpuPers;
$scope.IO = response.data.IO;
$scope.IOPS = response.data.IOPS;
$scope.memory = response.data.memory;
$scope.networkSpeed = response.data.networkSpeed;
if (response.data.enforce === 0) {
$scope.limitsInfoBox = false;
} else {
$scope.limitsInfoBox = true;
}
// Report Memory Usage
initDataMemory();
datasetMemory = [
{label: "Memory", data: memory, lines: {fill: true, lineWidth: 1.2}, color: "#00FF00"}
];
$.plot($("#memoryUsage"), datasetMemory, optionsMemory);
setTimeout(GetDataMemory, updateIntervalMemory);
// Report CPU Usage
initData();
dataset = [
{label: "CPU", data: cpu, lines: {fill: true, lineWidth: 1.2}, color: "#00FF00"}
];
$.plot($("#flot-placeholder1"), dataset, options);
setTimeout(GetData, updateInterval);
}
else {
new PNotify({
title: 'Operation Failed!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialDatas(response) {
$scope.cyberPanelLoading = true;
new PNotify({
title: 'Operation Failed!',
text: 'Could not connect to server, please refresh this page',
type: 'error'
});
}
};
$scope.fetchWebsiteLimits();
$scope.saveWebsiteLimits = function () {
$scope.cyberPanelLoading = false;
url = "/container/saveWebsiteLimits";
var data = {
'domain': $("#domain").text(),
'cpuPers': $scope.cpuPers,
'IO': $scope.IO,
'IOPS': $scope.IOPS,
'memory': $scope.memory,
'networkSpeed': $scope.networkSpeedBox,
'networkHandle': $scope.networkHandle,
'enforce': $scope.enforce
};
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: 'Changes successfully applied.',
type: 'success'
});
$scope.fetchWebsiteLimits();
}
else {
new PNotify({
title: 'Operation Failed!',
text: response.data.error_message,
type: 'error'
});
}
}
function cantLoadInitialDatas(response) {
$scope.cyberPanelLoading = true;
new PNotify({
title: 'Operation Failed!',
text: 'Could not connect to server, please refresh this page',
type: 'error'
});
}
};
});

View File

@@ -0,0 +1,87 @@
{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% block title %}{% trans "Limits - CyberPanel" %}{% endblock %}
{% block content %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div class="container">
<div id="page-title">
<h2 id="domainNamePage">{% trans "List Websites" %}</h2>
<p>{% trans "Launch and set limits for the websites." %}</p>
</div>
<div class="panel">
<div class="panel-body">
<h3 class="title-hero">
{% trans "Websites" %}
</h3>
<div ng-controller="listWebsites" class="example-box-wrapper">
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered"
id="datatable-example">
<thead>
<tr>
<th>Domain</th>
<th>Launch</th>
<th>IP Address</th>
<th>Package</th>
<th>Owner</th>
<th>State</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="web in WebSitesList track by $index">
<td ng-bind="web.domain"></td>
<td><a href="/container/manage/{$ web.domain $}"><img width="30px" height="30"
class="center-block"
src="{% static 'baseTemplate/assets/image-resources/webPanel.png' %}"></a>
</td>
<td ng-bind="web.ipAddress"></td>
<td ng-bind="web.package"></td>
<td ng-bind="web.admin"></td>
<td ng-bind="web.state"></td>
<td ng-bind="web.adminEmail"></td>
</tr>
</tbody>
</table>
<div id="listFail" class="alert alert-danger">
<p>{% trans "Cannot list websites. Error message:" %} {$ errorMessage $}</p>
</div>
<div class="row">
<div class="col-sm-4 col-sm-offset-8">
<nav aria-label="Page navigation">
<ul class="pagination">
<li ng-repeat="page in pagination" ng-click="getFurtherWebsitesFromDB($index+1)" id="webPages"><a
href="">{$ $index + 1 $}</a></li>
</ul>
</nav>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,67 @@
{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% block title %}{% trans "Not available - CyberPanel" %}{% endblock %}
{% block content %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div class="container">
<div id="page-title">
<h2>{% trans "Not available" %}</h2>
<p>{% trans "CyberPanel Ent is required for Containerization." %}</p>
</div>
{% if OLS %}
<div class="row">
<div class="col-sm-12">
<div class="alert alert-danger">
<p>{% trans "Containerization is only available on CyberPanel Ent. " %} <a target="_blank"
href="https://cyberpanel.net/docs/switching-from-openlitespeed-to-litespeed-enterprise-webserver/">Click
Here</a> {% trans " for conversion details." %}</p>
</div>
</div>
</div>
{% elif notInstalled %}
<div ng-controller="installContainer" class="panel">
<div class="panel-body">
<h3 class="title-hero">
{% trans "Install Packages" %} <img ng-hide="installDockerStatus"
src="{% static 'images/loading.gif' %}">
</h3>
<div class="example-box-wrapper">
<p>{% trans "Required packages are not installed on this server. Please proceed to installation." %}</p>
<!------ LSWS Switch box ----------------->
<div style="margin-top: 2%" ng-hide="installBoxGen" class="col-md-12">
<form action="/" id="" class="form-horizontal bordered-row">
<div class="form-group">
<div style="margin-top: 2%;" class="col-sm-12">
<textarea ng-model="requestData" rows="15"
class="form-control">{{ requestData }}</textarea>
</div>
</div>
</form>
</div>
<!----- LSWS Switch box ----------------->
<br>
<button class="btn btn-primary" ng-click="submitContainerInstall()">Install Now</button>
</div>
</div>
</div>
{% endif %}
</div>
{% endblock %}

View File

@@ -0,0 +1,186 @@
{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% block title %}{{ domain }}{% trans " limits - CyberPanel" %}{% endblock %}
{% block content %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div ng-controller="websiteContainerLimit" class="container">
<div id="page-title">
<h2 id="domainNamePage">{% trans "Limits/Usage" %}</h2> <img ng-hide="cyberPanelLoading"
src="{% static 'images/loading.gif' %}">
<p>{% trans "Set limits and view usage for " %} <span id="domain">{{ domain }}</span></p>
</div>
<button style="margin-bottom: 2%" class="btn btn-warning" data-toggle="modal" data-target="#settings"><i
class="fa fa-gear"></i> Edit Limits
</button>
<div ng-hide="limitsInfoBox" class="form-group">
<div class="alert alert-info">
<p>{% trans "Limits are not being inforced, click Edit Limits to inforace the limits." %}</p>
</div>
</div>
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered"
id="datatable-example">
<thead>
<tr>
<th>{% trans 'Limit' %}</th>
<th>{% trans 'Value' %}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{% trans 'CPU Percentage' %}</td>
<td>{$ cpuPers $}%</td>
</tr>
<tr>
<td>{% trans 'Memory' %}</td>
<td>{$ memory $}MB</td>
</tr>
<tr>
<td>{% trans 'I/O' %}</td>
<td>{$ IO $}MB/sec</td>
</tr>
<tr>
<td>{% trans 'IOPS' %}</td>
<td>{$ IOPS $}</td>
</tr>
<tr>
<td>{% trans 'Network Speed' %}</td>
<td>{$ networkSpeed $}</td>
</tr>
</tbody>
</table>
<div id="settings" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">Website Limits
<img id="containerSettingLoading" src="/static/images/loading.gif" style="display: none;">
</h4>
</div>
<div class="modal-body">
<form name="containerSettingsForm" action="/" class="form-horizontal">
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "CPU Percentage" %}</label>
<div class="col-sm-6">
<input name="memory" type="number" class="form-control" ng-model="cpuPers" required>
</div>
<div class="current-pack ng-binding">%</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Memory Limit" %}</label>
<div class="col-sm-6">
<input name="memory" type="number" class="form-control" ng-model="memory" required>
</div>
<div class="current-pack ng-binding">MB</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "I/O" %}</label>
<div class="col-sm-6">
<input name="memory" type="number" class="form-control" ng-model="IO" required>
</div>
<div class="current-pack ng-binding">MB</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "IOPS" %}</label>
<div class="col-sm-6">
<input name="memory" type="number" class="form-control" ng-model="IOPS" required>
</div>
<div class="current-pack ng-binding">Operations</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Network Speed" %}</label>
<div class="col-sm-4">
<input name="memory" type="number" class="form-control" ng-model="networkSpeedBox"
required>
</div>
<div class="col-sm-2">
<select ng-model="networkHandle" class="form-control">
<option>kbps</option>
<option>mbit</option>
</select>
</div>
</div>
<hr>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">Enforce Limits</label>
<div class="col-sm-9">
<div class="checkbox">
<label>
<input ng-model="enforce" type="checkbox" value=""
class="ng-pristine ng-untouched ng-valid ng-empty">
</label>
</div>
</div>
</div>
<br>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary"
ng-click="saveWebsiteLimits()" data-dismiss="modal">Save
</button>
<button type="button" class="btn btn-default" data-dismiss="modal">
Close
</button>
</div>
</div>
</div>
</div>
<div class="panel">
<div class="panel-body">
<h2 class="title-hero">
{% trans "CPU Usage of" %} {{ domain }}
</h2>
<div class="example-box-wrapper">
<div id="flot-placeholder1" style="width:auto;height:300px"></div>
</div>
</div>
<div class="panel-body">
<h2 class="title-hero">
{% trans "Memory Usage of" %} {{ domain }}
</h2>
<div class="example-box-wrapper">
<div id="memoryUsage" style="width:auto;height:300px"></div>
</div>
</div>
<div class="panel-body">
<h2 class="title-hero">
{% trans "Disk Usage of" %} {{ domain }}
</h2>
<div class="example-box-wrapper">
<div id="diskUsage" style="width:auto;height:300px"></div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.test import TestCase
# Create your tests here.

11
containerization/urls.py Normal file
View File

@@ -0,0 +1,11 @@
from django.conf.urls import url
import views
urlpatterns = [
url(r'^$', views.cHome, name='cHome'),
url(r'^submitContainerInstall$', views.submitContainerInstall, name='submitContainerInstall'),
url(r'^manage/(?P<domain>(.*))$', views.websiteContainerLimit, name='websiteContainerLimit'),
url(r'^fetchWebsiteLimits$', views.fetchWebsiteLimits, name='fetchWebsiteLimits'),
url(r'^saveWebsiteLimits$', views.saveWebsiteLimits, name='saveWebsiteLimits'),
url(r'^getUsageData$', views.getUsageData, name='getUsageData'),
]

351
containerization/views.py Normal file
View File

@@ -0,0 +1,351 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import HttpResponse, redirect
from loginSystem.views import loadLoginPage
from containerManager import ContainerManager
import json
from websiteFunctions.models import Websites
from .models import ContainerLimits
from random import randint
from plogical.processUtilities import ProcessUtilities
import os
import subprocess
import multiprocessing
from plogical.httpProc import httpProc
from plogical.acl import ACLManager
# Create your views here.
def cHome(request):
try:
templateName = 'containerization/listWebsites.html'
c = ContainerManager(request, templateName)
return c.renderC()
except KeyError:
return redirect(loadLoginPage)
def submitContainerInstall(request):
try:
userID = request.session['userID']
currentACL = ACLManager.loadedACL(userID)
if currentACL['admin'] == 1:
pass
else:
return ACLManager.loadErrorJson()
c = ContainerManager(request, None, 'submitContainerInstall')
c.start()
data_ret = {'status': 1, 'error_message': 'None'}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except BaseException, msg:
data_ret = {'status': 0, 'error_message': str(msg)}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
def websiteContainerLimit(request, domain):
try:
templateName = 'containerization/websiteContainerLimit.html'
data = {}
data['domain'] = domain
c = ContainerManager(request, templateName, None, data)
return c.renderC()
except KeyError:
return redirect(loadLoginPage)
def fetchWebsiteLimits(request):
try:
userID = request.session['userID']
currentACL = ACLManager.loadedACL(userID)
if currentACL['admin'] == 1:
pass
else:
return ACLManager.loadErrorJson()
data = json.loads(request.body)
domain = data['domain']
website = Websites.objects.get(domain=domain)
try:
websiteLimits = ContainerLimits.objects.get(owner=website)
except:
confPathTemp = "/home/cyberpanel/" + str(randint(1000, 9999))
confPath = '/etc/cgconfig.d/' + domain
count = ContainerLimits.objects.all().count() + 1
hexValue = ContainerManager.fetchHexValue(count)
cfs_quota_us = multiprocessing.cpu_count() * 10000
finalContent = ContainerManager.prepConf(website.externalApp, str(cfs_quota_us), str(100000), str(356), 1, 1024, hexValue)
if finalContent == 0:
return httpProc.AJAX(0, 'Please check CyberPanel main log file.')
writeToFile = open(confPathTemp, 'w')
writeToFile.write(finalContent)
writeToFile.close()
command = 'sudo mv ' + confPathTemp + ' ' + confPath
ProcessUtilities.executioner(command)
try:
os.remove(confPathTemp)
except:
pass
websiteLimits = ContainerLimits(owner=website, cpuPers='10', IO='1', IOPS='1024', memory='300', networkSpeed='1mbit', networkHexValue=hexValue)
websiteLimits.save()
finalData = {}
finalData['status'] = 1
finalData['cpuPers'] = int(websiteLimits.cpuPers)
finalData['IO'] = int(websiteLimits.IO)
finalData['IOPS'] = int(websiteLimits.IOPS)
finalData['memory'] = int(websiteLimits.memory)
finalData['networkSpeed'] = websiteLimits.networkSpeed
if websiteLimits.enforce == 1:
finalData['enforce'] = 1
else:
finalData['enforce'] = 0
json_data = json.dumps(finalData)
return HttpResponse(json_data)
except BaseException, msg:
data_ret = {'status': 0, 'error_message': str(msg)}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
def saveWebsiteLimits(request):
try:
userID = request.session['userID']
currentACL = ACLManager.loadedACL(userID)
if currentACL['admin'] == 1:
pass
else:
return ACLManager.loadErrorJson()
data = json.loads(request.body)
domain = data['domain']
cpuPers = data['cpuPers']
IO = data['IO']
IOPS = data['IOPS']
memory = data['memory']
networkSpeed = data['networkSpeed']
networkHandle = data['networkHandle']
try:
enforce = data['enforce']
except:
enforce = False
if cpuPers > 100:
return httpProc.AJAX(0, 'CPU Percentage can not be greater then 100%')
website = Websites.objects.get(domain=domain)
websiteLimits = ContainerLimits.objects.get(owner=website)
if enforce == True:
if websiteLimits.enforce == 0:
cgrulesTemp = "/home/cyberpanel/" + str(randint(1000, 9999))
cgrules = '/etc/cgrules.conf'
enforceString = '{} cpu,memory,blkio,net_cls {}/\n'.format(website.externalApp, website.externalApp)
cgrulesData = ProcessUtilities.outputExecutioner('sudo cat /etc/cgrules.conf').splitlines()
writeToFile = open(cgrulesTemp, 'w')
for items in cgrulesData:
writeToFile.writelines(items + '\n')
writeToFile.writelines(enforceString)
writeToFile.close()
command = 'sudo mv ' + cgrulesTemp + ' ' + cgrules
ProcessUtilities.executioner(command)
try:
os.remove(cgrulesTemp)
except:
pass
websiteLimits.enforce = 1
## Main Conf File
confPathTemp = "/home/cyberpanel/" + str(randint(1000, 9999))
confPath = '/etc/cgconfig.d/' + domain
cfs_quota_us = multiprocessing.cpu_count() * 1000
finalContent = ContainerManager.prepConf(website.externalApp, str(cpuPers * cfs_quota_us), str(100000),
str(memory), IO, IOPS, websiteLimits.networkHexValue)
if finalContent == 0:
return httpProc.AJAX(0, 'Please check CyberPanel main log file.')
writeToFile = open(confPathTemp, 'w')
writeToFile.write(finalContent)
writeToFile.close()
command = 'sudo mv ' + confPathTemp + ' ' + confPath
ProcessUtilities.executioner(command)
try:
os.remove(confPathTemp)
except:
pass
## Add Traffic Control / Restart Services
additionalArgs = {}
additionalArgs['classID'] = websiteLimits.id
additionalArgs['rateLimit'] = str(networkSpeed) + networkHandle
c = ContainerManager(None, None, 'addTrafficController', additionalArgs)
c.start()
else:
websiteLimits.enforce = 0
cgrulesTemp = "/home/cyberpanel/" + str(randint(1000, 9999))
cgrules = '/etc/cgrules.conf'
cgrulesData = ProcessUtilities.outputExecutioner('sudo cat /etc/cgrules.conf').splitlines()
writeToFile = open(cgrulesTemp, 'w')
for items in cgrulesData:
if items.find(website.externalApp) > -1:
continue
writeToFile.writelines(items + '\n')
writeToFile.close()
command = 'sudo mv ' + cgrulesTemp + ' ' + cgrules
ProcessUtilities.executioner(command)
confPath = '/etc/cgconfig.d/' + domain
command = 'sudo rm ' + confPath
ProcessUtilities.executioner(command)
## Not needed, to be removed later
additionalArgs = {}
additionalArgs['classID'] = websiteLimits.id
c = ContainerManager(None, None, 'removeLimits', additionalArgs)
c.start()
try:
os.remove(cgrulesTemp)
except:
pass
websiteLimits.cpuPers = str(cpuPers)
websiteLimits.memory = str(memory)
websiteLimits.IO = str(IO)
websiteLimits.IOPS = str(IOPS)
websiteLimits.networkSpeed = str(networkSpeed) + str(networkHandle)
websiteLimits.save()
finalData = {}
finalData['status'] = 1
json_data = json.dumps(finalData)
return HttpResponse(json_data)
except BaseException, msg:
data_ret = {'status': 0, 'error_message': str(msg)}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
def getUsageData(request):
try:
userID = request.session['userID']
currentACL = ACLManager.loadedACL(userID)
if currentACL['admin'] == 1:
pass
else:
return ACLManager.loadErrorJson()
data = json.loads(request.body)
domain = data['domain']
website = Websites.objects.get(domain=domain)
try:
type = data['type']
finalData = {}
finalData['status'] = 1
try:
if type == 'memory':
command = 'sudo cat /sys/fs/cgroup/memory/' + website.externalApp + '/memory.usage_in_bytes'
output = str(ProcessUtilities.outputExecutioner(command))
finalData['memory'] = int(float(output)/float(1024 * 1024))
elif type == 'io':
path = '/home/cyberpanel/' + website.externalApp
blkioPath = path + '/blkio'
if not os.path.exists(path):
os.mkdir(path)
command = 'sudo cat /sys/fs/cgroup/blkio/' + website.externalApp + '/blkio.throttle.io_service_bytes'
output = ProcessUtilities.outputExecutioner(command).splitlines()
readCurrent = output[0].split(' ')[2]
writeCurrent = output[1].split(' ')[2]
if os.path.exists(blkioPath):
old = open(blkioPath, 'r').read()
oldRead = float(old.split(',')[0])
oldWrite = float(old.split(',')[1])
finalData['readRate'] = int((float(readCurrent) - oldRead)/float(65536000))
finalData['writeRate'] = int((float(writeCurrent) - oldWrite) / float(65536000))
else:
finalData['readRate'] = 0
finalData['writeRate'] = 0
writeToFile = open(blkioPath, 'w')
writeToFile.write(readCurrent + ',' + writeCurrent)
writeToFile.close()
except:
finalData['memory'] = '0'
finalData['readRate'] = 0
finalData['writeRate'] = 0
except:
command = "top -b -n 1 -u " + website.externalApp + " | awk 'NR>7 { sum += $9; } END { print sum; }'"
output = str(subprocess.check_output(command, shell=True))
finalData = {}
finalData['status'] = 1
if len(output) == 0:
finalData['cpu'] = '0'
else:
finalData['cpu'] = str(float(output)/float(multiprocessing.cpu_count()))
final_json = json.dumps(finalData)
return HttpResponse(final_json)
except BaseException, msg:
data_ret = {'status': 0, 'error_message': str(msg), 'cpu': 0, 'memory':0}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)