diff --git a/.gitignore b/.gitignore index 0d20b6487..1b6d5405b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.pyc +containerization diff --git a/CyberCP/settings.py b/CyberCP/settings.py index 0dd5d5dd9..8cac18eab 100644 --- a/CyberCP/settings.py +++ b/CyberCP/settings.py @@ -65,7 +65,8 @@ INSTALLED_APPS = [ 'cloudAPI', 'highAvailability', 's3Backups', - 'dockerManager' + 'dockerManager', + 'containerization' ] MIDDLEWARE = [ diff --git a/CyberCP/urls.py b/CyberCP/urls.py index 644aa6156..fdfd5addc 100644 --- a/CyberCP/urls.py +++ b/CyberCP/urls.py @@ -41,4 +41,5 @@ urlpatterns = [ url(r'^emailMarketing/', include('emailMarketing.urls')), url(r'^cloudAPI/', include('cloudAPI.urls')), url(r'^docker/', include('dockerManager.urls')), + url(r'^container/', include('containerization.urls')), ] diff --git a/api/views.py b/api/views.py index b76582714..cce08c2e1 100644 --- a/api/views.py +++ b/api/views.py @@ -570,7 +570,7 @@ def changeAdminPassword(request): firstName="Cyber", lastName="Panel", acl=acl, token=token) admin.save() - vers = version(currentVersion="1.7", build=7) + vers = version(currentVersion="1.8", build=0) vers.save() package = Package(admin=admin, packageName="Default", diskSpace=1000, diff --git a/baseTemplate/templates/baseTemplate/index.html b/baseTemplate/templates/baseTemplate/index.html index 66026ffc3..8dce01542 100644 --- a/baseTemplate/templates/baseTemplate/index.html +++ b/baseTemplate/templates/baseTemplate/index.html @@ -96,6 +96,7 @@ href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css"> + @@ -115,6 +116,8 @@ }, 300); }); + + @@ -608,6 +611,24 @@
  • {% trans "Server" %}
  • + +
  • + + + {% trans "Containerization" %} + {% trans "NEW" %} + + +
  • +
  • @@ -886,6 +907,7 @@ + \ No newline at end of file diff --git a/baseTemplate/urls.py b/baseTemplate/urls.py index b249bf99e..7af0f42b6 100644 --- a/baseTemplate/urls.py +++ b/baseTemplate/urls.py @@ -11,7 +11,6 @@ urlpatterns = [ #url(r'^upgrade',views.upgrade, name='upgrade'), url(r'^UpgradeStatus',views.upgradeStatus, name='UpgradeStatus'), - url(r'^upgradeVersion',views.upgradeVersion, name='upgradeVersion'), diff --git a/cloudAPI/views.py b/cloudAPI/views.py index e2c0e0a88..a1855b50a 100644 --- a/cloudAPI/views.py +++ b/cloudAPI/views.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals from cloudManager import CloudManager import json from loginSystem.models import Administrator +from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging def router(request): try: @@ -13,6 +14,7 @@ def router(request): serverUserName = data['serverUserName'] admin = Administrator.objects.get(userName=serverUserName) + cm = CloudManager(data, admin) if controller == 'statusFunc': diff --git a/dockerManager/container.py b/dockerManager/container.py new file mode 100644 index 000000000..f1abfa687 --- /dev/null +++ b/dockerManager/container.py @@ -0,0 +1,1120 @@ +#!/usr/local/CyberCP/bin/python2 +from __future__ import division +import os +import os.path +import sys +import django +import mimetypes + +sys.path.append('/usr/local/CyberCP') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings") +django.setup() +import json +from plogical.acl import ACLManager +import plogical.CyberCPLogFileWriter as logging +from django.shortcuts import HttpResponse, render, redirect +from loginSystem.models import Administrator +import subprocess +import shlex +import time +from dockerManager.models import Containers +from math import ceil +import docker +import docker.utils +import requests +from plogical.processUtilities import ProcessUtilities +from serverStatus.serverStatusUtil import ServerStatusUtil +import threading as multi +from plogical.mailUtilities import mailUtilities + + +# Use default socket to connect +class ContainerManager(multi.Thread): + + def __init__(self, name=None, function=None, request = None, templateName = None, data = None): + multi.Thread.__init__(self) + self.name = name + self.function = function + self.request = request + self.templateName = templateName + self.data = data + + def renderDM(self): + + userID = self.request.session['userID'] + currentACL = ACLManager.loadedACL(userID) + + if currentACL['admin'] == 1: + pass + else: + return ACLManager.loadError() + + return render(self.request, self.templateName, self.data) + + def run(self): + try: + if self.function == 'submitInstallDocker': + self.submitInstallDocker() + elif self.function == 'restartGunicorn': + command = 'sudo systemctl restart gunicorn.socket' + ProcessUtilities.executioner(command) + except BaseException, msg: + logging.CyberCPLogFileWriter.writeToFile( str(msg) + ' [ContainerManager.run]') + + @staticmethod + def executioner(command, statusFile): + try: + res = subprocess.call(shlex.split(command), stdout=statusFile, stderr=statusFile) + if res == 1: + return 0 + else: + return 1 + except BaseException, msg: + logging.CyberCPLogFileWriter.writeToFile(str(msg)) + return 0 + + def submitInstallDocker(self): + try: + currentACL = ACLManager.loadedACL(self.name) + + if ACLManager.currentContextPermission(currentACL, 'createContainer') == 0: + return ACLManager.loadError() + + + mailUtilities.checkHome() + + statusFile = open(ServerStatusUtil.lswsInstallStatusPath, 'w') + + logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, + "Starting Docker Installation..\n", 1) + + command = "sudo adduser docker" + ServerStatusUtil.executioner(command, statusFile) + + command = 'sudo groupadd docker' + ServerStatusUtil.executioner(command, statusFile) + + command = 'sudo usermod -aG docker docker' + ServerStatusUtil.executioner(command, statusFile) + + command = 'sudo usermod -aG docker cyberpanel' + ServerStatusUtil.executioner(command, statusFile) + + if ProcessUtilities.decideDistro() == ProcessUtilities.centos: + command = 'sudo yum install -y docker' + else: + command = 'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y docker.io' + + if not ServerStatusUtil.executioner(command, statusFile): + logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, + "Failed to install Docker. [404]\n", 1) + return 0 + + command = 'sudo systemctl enable docker' + ServerStatusUtil.executioner(command, statusFile) + + command = 'sudo systemctl start docker' + ServerStatusUtil.executioner(command, statusFile) + + logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, + "Docker successfully installed.[200]\n", 1) + + time.sleep(2) + + cm = ContainerManager(self.name, 'restartGunicorn') + cm.start() + + except BaseException, msg: + logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, str(msg) + ' [404].', 1) + + def createContainer(self, request=None, userID=None, data=None): + try: + admin = Administrator.objects.get(pk=userID) + if admin.acl.adminStatus != 1: + return ACLManager.loadError() + + client = docker.from_env() + dockerAPI = docker.APIClient() + + adminNames = ACLManager.loadAllUsers(userID) + tag = request.GET.get('tag') + image = request.GET.get('image') + tag = tag.split(" (")[0] + + if "/" in image: + name = image.split("/")[0] + "." + image.split("/")[1] + else: + name = image + + try: + inspectImage = dockerAPI.inspect_image(image + ":" + tag) + except docker.errors.ImageNotFound: + val = request.session['userID'] + admin = Administrator.objects.get(pk=val) + return render(request, 'dockerManager/images.html', {"type": admin.type, + 'image': image, + 'tag': tag}) + + envList = {}; + if 'Env' in inspectImage['Config']: + for item in inspectImage['Config']['Env']: + if '=' in item: + splitedItem = item.split('=', 1) + print splitedItem + envList[splitedItem[0]] = splitedItem[1] + else: + envList[item] = "" + + portConfig = {}; + if 'ExposedPorts' in inspectImage['Config']: + for item in inspectImage['Config']['ExposedPorts']: + portDef = item.split('/') + portConfig[portDef[0]] = portDef[1] + + if image is None or image is '' or tag is None or tag is '': + return redirect(loadImages) + + Data = {"ownerList": adminNames, "image": image, "name": name, "tag": tag, "portConfig": portConfig, + "envList": envList} + + return render(request, 'dockerManager/runContainer.html', Data) + + except BaseException, msg: + return HttpResponse(str(msg)) + + def loadContainerHome(self, request=None, userID=None, data=None): + name = self.name + + if ACLManager.checkContainerOwnership(name, userID) != 1: + return ACLManager.loadError() + + client = docker.from_env() + dockerAPI = docker.APIClient() + try: + container = client.containers.get(name) + except docker.errors.NotFound as err: + return HttpResponse("Container not found") + + data = {} + con = Containers.objects.get(name=name) + data['name'] = name + data['image'] = con.image + ":" + con.tag + data['ports'] = json.loads(con.ports) + data['cid'] = con.cid + data['envList'] = json.loads(con.env) + data['volList'] = json.loads(con.volumes) + + stats = container.stats(decode=False, stream=False) + logs = container.logs(stream=True) + + data['status'] = container.status + data['memoryLimit'] = con.memory + if con.startOnReboot == 1: + data['startOnReboot'] = 'true' + data['restartPolicy'] = "Yes" + else: + data['startOnReboot'] = 'false' + data['restartPolicy'] = "No" + + if 'usage' in stats['memory_stats']: + # Calculate Usage + # Source: https://github.com/docker/docker/blob/28a7577a029780e4533faf3d057ec9f6c7a10948/api/client/stats.go#L309 + data['memoryUsage'] = (stats['memory_stats']['usage'] / stats['memory_stats']['limit']) * 100 + + cpu_count = len(stats["cpu_stats"]["cpu_usage"]["percpu_usage"]) + data['cpuUsage'] = 0.0 + cpu_delta = float(stats["cpu_stats"]["cpu_usage"]["total_usage"]) - \ + float(stats["precpu_stats"]["cpu_usage"]["total_usage"]) + system_delta = float(stats["cpu_stats"]["system_cpu_usage"]) - \ + float(stats["precpu_stats"]["system_cpu_usage"]) + if system_delta > 0.0: + data['cpuUsage'] = round(cpu_delta / system_delta * 100.0 * cpu_count, 3) + else: + data['memoryUsage'] = 0 + data['cpuUsage'] = 0 + + return render(request, 'dockerManager/viewContainer.html', data) + + def listContainers(self, request=None, userID=None, data=None): + try: + client = docker.from_env() + dockerAPI = docker.APIClient() + + currentACL = ACLManager.loadedACL(userID) + containers = ACLManager.findAllContainers(currentACL, userID) + + allContainers = client.containers.list() + containersList = [] + showUnlistedContainer = True + + # TODO: Add condition to show unlisted Containers only if user has admin level access + + unlistedContainers = [] + for container in allContainers: + if container.name not in containers: + unlistedContainers.append(container) + + if not unlistedContainers: + showUnlistedContainer = False + + adminNames = ACLManager.loadAllUsers(userID) + + pages = float(len(containers)) / float(10) + pagination = [] + + if pages <= 1.0: + pages = 1 + pagination.append('
  • ') + else: + pages = ceil(pages) + finalPages = int(pages) + 1 + + for i in range(1, finalPages): + pagination.append('
  • ' + str(i) + '
  • ') + + return render(request, 'dockerManager/listContainers.html', {"pagination": pagination, + "unlistedContainers": unlistedContainers, + "adminNames": adminNames, + "showUnlistedContainer": showUnlistedContainer}) + except BaseException, msg: + return HttpResponse(str(msg)) + + def getContainerLogs(self, userID=None, data=None): + try: + name = data['name'] + + # Check if container is registered in database or unlisted + if Containers.objects.filter(name=name).exists(): + if ACLManager.checkContainerOwnership(name, userID) != 1: + return ACLManager.loadErrorJson('containerLogStatus', 0) + + client = docker.from_env() + dockerAPI = docker.APIClient() + + container = client.containers.get(name) + logs = container.logs() + + data_ret = {'containerLogStatus': 1, 'containerLog': logs, 'error_message': "None"} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + + except BaseException, msg: + data_ret = {'containerLogStatus': 0, 'containerLog': 'Error', 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + def submitContainerCreation(self, userID=None, data=None): + try: + + admin = Administrator.objects.get(pk=userID) + if admin.acl.adminStatus != 1: + return ACLManager.loadErrorJson('createContainerStatus', 0) + + client = docker.from_env() + dockerAPI = docker.APIClient() + + name = data['name'] + image = data['image'] + tag = data['tag'] + dockerOwner = data['dockerOwner'] + memory = data['memory'] + envList = data['envList'] + volList = data['volList'] + + inspectImage = dockerAPI.inspect_image(image + ":" + tag) + portConfig = {} + + # Formatting envList for usage + envDict = {} + for key, value in envList.iteritems(): + if (value['name'] != '') or (value['value'] != ''): + envDict[value['name']] = value['value'] + + if 'ExposedPorts' in inspectImage['Config']: + for item in inspectImage['Config']['ExposedPorts']: + # Do not allow priviledged port numbers + if int(data[item]) < 1024 or int(data[item]) > 65535: + data_ret = {'createContainerStatus': 0, 'error_message': "Choose port between 1024 and 65535"} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + portConfig[item] = data[item] + + volumes = {} + for index, volume in volList.iteritems(): + volumes[volume['src']] = {'bind': volume['dest'], + 'mode': 'rw'} + + ## Create Configurations + admin = Administrator.objects.get(userName=dockerOwner) + + containerArgs = {'image': image + ":" + tag, + 'detach': True, + 'name': name, + 'ports': portConfig, + 'publish_all_ports': True, + 'environment': envDict, + 'volumes': volumes} + + containerArgs['mem_limit'] = memory * 1048576; # Converts MB to bytes ( 0 * x = 0 for unlimited memory) + + try: + container = client.containers.create(**containerArgs) + except Exception as err: + if "port is already allocated" in err: # We need to delete container if port is not available + print "Deleting container" + container.remove(force=True) + data_ret = {'createContainerStatus': 0, 'error_message': str(err)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + con = Containers(admin=admin, + name=name, + tag=tag, + image=image, + memory=memory, + ports=json.dumps(portConfig), + volumes=json.dumps(volumes), + env=json.dumps(envDict), + cid=container.id) + + con.save() + + data_ret = {'createContainerStatus': 1, 'error_message': "None"} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + + except BaseException, msg: + data_ret = {'createContainerStatus': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + def submitInstallImage(self, userID=None, data=None): + try: + + admin = Administrator.objects.get(pk=userID) + if admin.acl.adminStatus != 1: + return ACLManager.loadErrorJson('installImageStatus', 0) + + client = docker.from_env() + dockerAPI = docker.APIClient() + + image = data['image'] + tag = data['tag'] + + try: + inspectImage = dockerAPI.inspect_image(image + ":" + tag) + data_ret = {'installImageStatus': 0, 'error_message': "Image already installed"} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + except docker.errors.ImageNotFound: + pass + + try: + image = client.images.pull(image, tag=tag) + print image.id + except docker.errors.APIError as msg: + data_ret = {'installImageStatus': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + data_ret = {'installImageStatus': 1, 'error_message': "None"} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + + except BaseException, msg: + data_ret = {'installImageStatus': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + def submitContainerDeletion(self, userID=None, data=None, called=False): + try: + name = data['name'] + # Check if container is registered in database or unlisted + if Containers.objects.filter(name=name).exists(): + if ACLManager.checkContainerOwnership(name, userID) != 1: + if called: + return 'Permission error' + else: + return ACLManager.loadErrorJson('websiteDeleteStatus', 0) + + client = docker.from_env() + dockerAPI = docker.APIClient() + + unlisted = data['unlisted'] + + if 'force' in data: + force = True + else: + force = False + + if not unlisted: + containerOBJ = Containers.objects.get(name=name) + + if not force: + try: + container = client.containers.get(name) + except docker.errors.NotFound as err: + if called: + return 'Container does not exist' + else: + data_ret = {'delContainerStatus': 2, 'error_message': 'Container does not exist'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + try: + container.stop() # Stop container + container.kill() # INCASE graceful stop doesn't work + except: + pass + + try: + container.remove() # Finally remove container + except docker.errors.APIError as err: + data_ret = {'delContainerStatus': 0, 'error_message': str(err)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + except: + if called: + return "Unknown" + else: + data_ret = {'delContainerStatus': 0, 'error_message': 'Unknown error'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + if not unlisted and not called: + containerOBJ.delete() + + if called: + return 0 + else: + data_ret = {'delContainerStatus': 1, 'error_message': "None"} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + except BaseException, msg: + if called: + return str(msg) + else: + data_ret = {'delContainerStatus': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + def getContainerList(self, userID=None, data=None): + try: + admin = Administrator.objects.get(pk=userID) + if admin.acl.adminStatus != 1: + return ACLManager.loadErrorJson('listContainerStatus', 0) + + currentACL = ACLManager.loadedACL(userID) + pageNumber = int(data['page']) + json_data = self.findContainersJson(currentACL, userID, pageNumber) + final_dic = {'listContainerStatus': 1, 'error_message': "None", "data": json_data} + final_json = json.dumps(final_dic) + return HttpResponse(final_json) + except BaseException, msg: + dic = {'listContainerStatus': 0, 'error_message': str(msg)} + json_data = json.dumps(dic) + return HttpResponse(json_data) + + def findContainersJson(self, currentACL, userID, pageNumber): + admin = Administrator.objects.get(pk=userID) + if admin.acl.adminStatus != 1: + return ACLManager.loadError() + + finalPageNumber = ((pageNumber * 10)) - 10 + endPageNumber = finalPageNumber + 10 + containers = ACLManager.findContainersObjects(currentACL, userID)[finalPageNumber:endPageNumber] + + json_data = "[" + checker = 0 + + for items in containers: + dic = {'name': items.name, 'admin': items.admin.userName, 'tag': items.tag, 'image': items.image} + + if checker == 0: + json_data = json_data + json.dumps(dic) + checker = 1 + else: + json_data = json_data + ',' + json.dumps(dic) + + json_data = json_data + ']' + + return json_data + + def doContainerAction(self, userID=None, data=None): + try: + + name = data['name'] + if ACLManager.checkContainerOwnership(name, userID) != 1: + return ACLManager.loadErrorJson('containerActionStatus', 0) + + client = docker.from_env() + dockerAPI = docker.APIClient() + + action = data['action'] + try: + container = client.containers.get(name) + except docker.errors.NotFound as err: + data_ret = {'containerActionStatus': 0, 'error_message': 'Container does not exist'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + except: + data_ret = {'containerActionStatus': 0, 'error_message': 'Unknown'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + try: + if action == 'start': + container.start() + elif action == 'stop': + container.stop() + elif action == 'restart': + container.restart() + else: + data_ret = {'containerActionStatus': 0, 'error_message': 'Unknown Action'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + except docker.errors.APIError as err: + data_ret = {'containerActionStatus': 0, 'error_message': str(err)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + time.sleep(3) # Wait 3 seconds for container to finish starting/stopping/restarting + status = container.status + data_ret = {'containerActionStatus': 1, 'error_message': 'None', 'status': status} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + except BaseException, msg: + data_ret = {'containerActionStatus': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + def getContainerStatus(self, userID=None, data=None): + try: + name = data['name'] + if ACLManager.checkContainerOwnership(name, userID) != 1: + return ACLManager.loadErrorJson('containerStatus', 0) + + client = docker.from_env() + dockerAPI = docker.APIClient() + + try: + container = client.containers.get(name) + except docker.errors.NotFound as err: + data_ret = {'containerStatus': 0, 'error_message': 'Container does not exist'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + except: + data_ret = {'containerStatus': 0, 'error_message': 'Unknown'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + status = container.status + data_ret = {'containerStatus': 1, 'error_message': 'None', 'status': status} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + except BaseException, msg: + data_ret = {'containerStatus': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + def exportContainer(self, request=None, userID=None, data=None): + try: + name = request.GET.get('name') + if ACLManager.checkContainerOwnership(name, userID) != 1: + return ACLManager.loadErrorJson('containerStatus', 0) + + client = docker.from_env() + dockerAPI = docker.APIClient() + + try: + container = client.containers.get(name) + except docker.errors.NotFound as err: + data_ret = {'containerStatus': 0, 'error_message': 'Container does not exist'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + except: + data_ret = {'containerStatus': 0, 'error_message': 'Unknown'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + eFile = container.export() # Export with default chunk size + response = HttpResponse(eFile, content_type='application/force-download') + response['Content-Disposition'] = 'attachment; filename="' + name + '.tar"' + return response + + except BaseException, msg: + data_ret = {'containerStatus': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + def getContainerTop(self, userID=None, data=None): + try: + name = data['name'] + if ACLManager.checkContainerOwnership(name, userID) != 1: + return ACLManager.loadErrorJson('containerTopStatus', 0) + + client = docker.from_env() + dockerAPI = docker.APIClient() + + try: + container = client.containers.get(name) + except docker.errors.NotFound as err: + data_ret = {'containerTopStatus': 0, 'error_message': 'Container does not exist'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + except: + data_ret = {'containerTopStatus': 0, 'error_message': 'Unknown'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + try: + top = container.top() + except docker.errors.APIError as err: + data_ret = {'containerTopStatus': 0, 'error_message': str(err)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + data_ret = {'containerTopStatus': 1, 'error_message': 'None', 'processes': top} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + except BaseException, msg: + data_ret = {'containerTopStatus': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + def assignContainer(self, userID=None, data=None): + try: + # Todo: add check only for super user i.e. main admin + admin = Administrator.objects.get(pk=userID) + if admin.acl.adminStatus != 1: + return ACLManager.loadErrorJson('assignContainerStatus', 0) + + client = docker.from_env() + dockerAPI = docker.APIClient() + + name = data['name'] + dockerOwner = data['admin'] + + admin = Administrator.objects.get(userName=dockerOwner) + + try: + container = client.containers.get(name) + except docker.errors.NotFound as err: + data_ret = {'assignContainerStatus': 0, 'error_message': 'Container does not exist'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + except: + data_ret = {'assignContainerStatus': 0, 'error_message': 'Unknown'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + con = Containers(admin=admin, + name=name, + cid=container.id) + + con.save() + + data_ret = {'assignContainerStatus': 1, 'error_message': 'None'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + except BaseException, msg: + data_ret = {'assignContainerStatus': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + def searchImage(self, userID=None, data=None): + try: + admin = Administrator.objects.get(pk=userID) + if admin.acl.adminStatus != 1: + return ACLManager.loadErrorJson('searchImageStatus', 0) + + client = docker.from_env() + dockerAPI = docker.APIClient() + + string = data['string'] + try: + matches = client.images.search(term=string) + except docker.errors.APIError as err: + data_ret = {'searchImageStatus': 0, 'error_message': str(err)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + except: + data_ret = {'searchImageStatus': 0, 'error_message': 'Unknown'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + print json.dumps(matches) + + for image in matches: + if "/" in image['name']: + image['name2'] = image['name'].split("/")[0] + ":" + image['name'].split("/")[1] + else: + image['name2'] = image['name'] + + data_ret = {'searchImageStatus': 1, 'error_message': 'None', 'matches': matches} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + except BaseException, msg: + data_ret = {'searchImageStatus': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + def images(self, request=None, userID=None, data=None): + try: + admin = Administrator.objects.get(pk=userID) + if admin.acl.adminStatus != 1: + return ACLManager.loadError() + + client = docker.from_env() + dockerAPI = docker.APIClient() + + try: + imageList = client.images.list() + except docker.errors.APIError as err: + return HttpResponse(str(err)) + + images = {} + names = [] + + for image in imageList: + name = image.attrs['RepoTags'][0].split(":")[0] + if "/" in name: + name2 = "" + for item in name.split("/"): + name2 += ":" + item + else: + name2 = name + + tags = [] + for tag in image.tags: + getTag = tag.split(":") + if len(getTag) == 2: + tags.append(getTag[1]) + print tags + if name in names: + images[name]['tags'].extend(tags) + else: + names.append(name) + images[name] = {"name": name, + "name2": name2, + "tags": tags} + print "======" + print images + return render(request, 'dockerManager/images.html', {"images": images, "test": ''}) + + except BaseException, msg: + return HttpResponse(str(msg)) + + def manageImages(self, request=None, userID=None, data=None): + try: + currentACL = ACLManager.loadedACL(userID) + + if currentACL['admin'] == 1: + pass + else: + return ACLManager.loadError() + + client = docker.from_env() + dockerAPI = docker.APIClient() + + imageList = client.images.list() + + images = {} + names = [] + + for image in imageList: + name = image.attrs['RepoTags'][0].split(":")[0] + if name in names: + images[name]['tags'].extend(image.tags) + else: + names.append(name) + images[name] = {"name": name, + "tags": image.tags} + + return render(request, 'dockerManager/manageImages.html', {"images": images}) + + except BaseException, msg: + return HttpResponse(str(msg)) + + def getImageHistory(self, userID=None, data=None): + try: + + name = data['name'] + + client = docker.from_env() + dockerAPI = docker.APIClient() + + try: + image = client.images.get(name) + except docker.errors.APIError as err: + data_ret = {'imageHistoryStatus': 0, 'error_message': str(err)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + except: + data_ret = {'imageHistoryStatus': 0, 'error_message': 'Unknown'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + data_ret = {'imageHistoryStatus': 1, 'error_message': 'None', 'history': image.history()} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + except BaseException, msg: + data_ret = {'imageHistoryStatus': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + def removeImage(self, userID=None, data=None): + try: + admin = Administrator.objects.get(pk=userID) + + if admin.acl.adminStatus != 1: + return ACLManager.loadError() + + client = docker.from_env() + dockerAPI = docker.APIClient() + + name = data['name'] + try: + if name == 0: + action = client.images.prune() + else: + action = client.images.remove(name) + print action + except docker.errors.APIError as err: + data_ret = {'removeImageStatus': 0, 'error_message': str(err)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + except: + data_ret = {'removeImageStatus': 0, 'error_message': 'Unknown'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + data_ret = {'removeImageStatus': 1, 'error_message': 'None'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + except BaseException, msg: + data_ret = {'removeImageStatus': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + # Internal function for recreating containers + + def doRecreateContainer(self, userID, data, con): + try: + + client = docker.from_env() + dockerAPI = docker.APIClient() + + name = data['name'] + unlisted = data['unlisted'] # Pass this as 1 if image is not known for container + image = data['image'] + tag = data['tag'] + env = data['env'] + volumes = data['volumes'] + port = data['ports'] + memory = data['memory'] + + if image == 'unknown': + return "Image name not known" + # Call container delete function + delStatus = self.submitContainerDeletion(userID, data, True) + if delStatus != 0: + return delStatus + + containerArgs = {'image': image + ":" + tag, + 'detach': True, + 'name': name, + 'ports': port, + 'environment': env, + 'volumes': volumes, + 'publish_all_ports': True, + 'mem_limit': memory * 1048576} + + if con.startOnReboot == 1: + containerArgs['restart_policy'] = {"Name": "always"} + + container = client.containers.create(**containerArgs) + con.cid = container.id + con.save() + + return 0 + except BaseException, msg: + return str(msg) + + def saveContainerSettings(self, userID=None, data=None): + try: + name = data['name'] + if ACLManager.checkContainerOwnership(name, userID) != 1: + return ACLManager.loadErrorJson('saveSettingsStatus', 0) + + client = docker.from_env() + dockerAPI = docker.APIClient() + + memory = data['memory'] + startOnReboot = data['startOnReboot'] + envList = data['envList'] + volList = data['volList'] + + if startOnReboot == True: + startOnReboot = 1 + rPolicy = {"Name": "always"} + else: + startOnReboot = 0 + rPolicy = {} + + try: + container = client.containers.get(name) + except docker.errors.NotFound as err: + data_ret = {'saveSettingsStatus': 0, 'error_message': 'Container does not exist'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + except: + data_ret = {'saveSettingsStatus': 0, 'error_message': 'Unknown'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + try: + container.update(mem_limit=memory * 1048576, + restart_policy=rPolicy) + except docker.errors.APIError as err: + data_ret = {'saveSettingsStatus': 0, 'error_message': str(err)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + con = Containers.objects.get(name=name) + con.memory = memory + con.startOnReboot = startOnReboot + + if 'envConfirmation' in data and data['envConfirmation']: + # Formatting envList for usage + envDict = {} + for key, value in envList.iteritems(): + if (value['name'] != '') or (value['value'] != ''): + envDict[value['name']] = value['value'] + + volumes = {} + for index, volume in volList.iteritems(): + volumes[volume['src']] = {'bind': volume['dest'], + 'mode': 'rw'} + # Prepare data for recreate function + data = { + 'name': name, + 'unlisted': 0, + 'image': con.image, + 'tag': con.tag, + 'env': envDict, + 'ports': json.loads(con.ports), + 'volumes': volumes, + 'memory': con.memory + } + + recreateStatus = self.doRecreateContainer(userID, data, con) + if recreateStatus != 0: + data_ret = {'saveSettingsStatus': 0, 'error_message': str(recreateStatus)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + con.env = json.dumps(envDict) + con.volumes = json.dumps(volumes) + con.save() + + data_ret = {'saveSettingsStatus': 1, 'error_message': 'None'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + except BaseException, msg: + data_ret = {'saveSettingsStatus': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + def recreateContainer(self, userID=None, data=None): + try: + name = data['name'] + if ACLManager.checkContainerOwnership(name, userID) != 1: + return ACLManager.loadErrorJson('saveSettingsStatus', 0) + + client = docker.from_env() + dockerAPI = docker.APIClient() + + try: + container = client.containers.get(name) + except docker.errors.NotFound as err: + data_ret = {'recreateContainerStatus': 0, 'error_message': 'Container does not exist'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + except: + data_ret = {'recreateContainerStatus': 0, 'error_message': 'Unknown'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + con = Containers.objects.get(name=name) + + # Prepare data for recreate function + data = { + 'name': name, + 'unlisted': 0, + 'image': con.image, + 'tag': con.tag, + 'env': json.loads(con.env), + 'ports': json.loads(con.ports), + 'volumes': json.loads(con.volumes), + # No filter needed now as its ports are filtered when adding to database + 'memory': con.memory + } + + recreateStatus = self.doRecreateContainer(userID, data, con) + if recreateStatus != 0: + data_ret = {'recreateContainerStatus': 0, 'error_message': str(recreateStatus)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + data_ret = {'recreateContainerStatus': 1, 'error_message': 'None'} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + except BaseException, msg: + data_ret = {'recreateContainerStatus': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + def getTags(self, userID=None, data=None): + try: + + admin = Administrator.objects.get(pk=userID) + if admin.acl.adminStatus != 1: + return ACLManager.loadError() + + image = data['image'] + page = data['page'] + + if ":" in image: + image2 = image.split(":")[0] + "/" + image.split(":")[1] + else: + image2 = "library/" + image + + print image + registryData = requests.get('https://registry.hub.docker.com/v2/repositories/' + image2 + '/tags', + {'page': page}).json() + + tagList = [] + for tag in registryData['results']: + tagList.append(tag['name']) + + data_ret = {'getTagsStatus': 1, 'list': tagList, 'next': registryData['next'], 'error_message': None} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + except BaseException, msg: + data_ret = {'getTagsStatus': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) \ No newline at end of file diff --git a/dockerManager/decorators.py b/dockerManager/decorators.py index d2320b7ba..30eca4c7b 100644 --- a/dockerManager/decorators.py +++ b/dockerManager/decorators.py @@ -5,6 +5,7 @@ import docker import json from django.http import HttpResponse from loginSystem.views import loadLoginPage +from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging def preDockerRun(function): def wrap(request, *args, **kwargs): @@ -36,7 +37,8 @@ def preDockerRun(function): try: client = docker.from_env() client.ping() - except: + except BaseException, msg: + logging.writeToFile(str(msg)) if isPost: data_ret = {'status': 0, 'error_message': 'Docker daemon not running or not responsive'} json_data = json.dumps(data_ret) @@ -45,4 +47,5 @@ def preDockerRun(function): return render(request, 'dockerManager/install.html', {'status':admin.type, 'conErr':1}) return function(request, *args, **kwargs) + return wrap \ No newline at end of file diff --git a/dockerManager/models.py b/dockerManager/models.py index b54527d4e..75d7328bc 100644 --- a/dockerManager/models.py +++ b/dockerManager/models.py @@ -13,5 +13,6 @@ class Containers(models.Model): tag = models.CharField(max_length=50, default='unknown') memory = models.IntegerField(default=0) ports = models.TextField(default="{}") + volumes = models.TextField(default="{}") env = models.TextField(default="{}") startOnReboot = models.IntegerField(default=0) diff --git a/dockerManager/static/dockerManager/dockerManager.js b/dockerManager/static/dockerManager/dockerManager.js index 96421e682..e77e55ed6 100644 --- a/dockerManager/static/dockerManager/dockerManager.js +++ b/dockerManager/static/dockerManager/dockerManager.js @@ -1,5 +1,3 @@ - - app.controller('installDocker', function ($scope, $http, $timeout, $window) { $scope.installDockerStatus = true; $scope.installBoxGen = true; @@ -120,18 +118,27 @@ app.controller('runContainer', function ($scope, $http) { $scope.couldNotConnect = true; $scope.goBackDisable = true; + $scope.volList = {}; + $scope.volListNumber = 0; + $scope.addVolField = function () { + $scope.volList[$scope.volListNumber] = {'dest': '', 'src': ''}; + $scope.volListNumber = $scope.volListNumber + 1; + console.log($scope.volList) + }; + $scope.removeVolField = function () { + delete $scope.volList[$scope.volListNumber - 1]; + $scope.volListNumber = $scope.volListNumber - 1; + }; + $scope.addEnvField = function () { var countEnv = Object.keys($scope.envList).length; $scope.envList[countEnv + 1] = {'name': '', 'value': ''}; - } + }; var statusFile; $scope.createContainer = function () { - console.log($scope.iport); - console.log($scope.portType); - $scope.containerCreationLoading = true; $scope.installationDetailsForm = true; $scope.installationProgress = false; @@ -157,7 +164,8 @@ app.controller('runContainer', function ($scope, $http) { memory: memory, dockerOwner: dockerOwner, image: image, - envList: $scope.envList + envList: $scope.envList, + volList: $scope.volList }; @@ -165,8 +173,6 @@ app.controller('runContainer', function ($scope, $http) { data[port + "/" + protocol] = $scope.eport[port]; }); - console.log(data) - var config = { headers: { 'X-CSRFToken': getCookie('csrftoken') @@ -314,7 +320,7 @@ app.controller('listContainers', function ($scope, $http) { if (response.data.delContainerStatus === 1) { location.reload(); } - else if (response.data.delContainerStatus == 2) { + else if (response.data.delContainerStatus === 2) { (new PNotify({ title: response.data.error_message, text: 'Delete anyway?', @@ -382,7 +388,6 @@ app.controller('listContainers', function ($scope, $http) { else { name = $scope.activeLog; } - console.log(name) $scope.logs = "Loading..."; url = "/docker/getContainerLogs"; @@ -420,7 +425,7 @@ app.controller('listContainers', function ($scope, $http) { type: 'error' }); } - } + }; url = "/docker/getContainerList"; @@ -697,7 +702,16 @@ app.controller('viewContainer', function ($scope, $http) { }); } - } + }; + + $scope.addVolField = function () { + $scope.volList[$scope.volListNumber] = {'dest': '', 'src': ''}; + $scope.volListNumber = $scope.volListNumber + 1; + }; + $scope.removeVolField = function () { + delete $scope.volList[$scope.volListNumber - 1]; + $scope.volListNumber = $scope.volListNumber - 1; + }; $scope.saveSettings = function () { $('#containerSettingLoading').show(); @@ -709,10 +723,11 @@ app.controller('viewContainer', function ($scope, $http) { memory: $scope.memory, startOnReboot: $scope.startOnReboot, envConfirmation: $scope.envConfirmation, - envList: $scope.envList + envList: $scope.envList, + volList: $scope.volList }; - console.log(data) + var config = { headers: { 'X-CSRFToken': getCookie('csrftoken') diff --git a/dockerManager/templates/dockerManager/runContainer.html b/dockerManager/templates/dockerManager/runContainer.html index f801432fd..fde7d81d5 100644 --- a/dockerManager/templates/dockerManager/runContainer.html +++ b/dockerManager/templates/dockerManager/runContainer.html @@ -107,11 +107,38 @@ - -

    + +
    + +
    +
    + +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    + +
    + +

    +
    diff --git a/dockerManager/templates/dockerManager/viewContainer.html b/dockerManager/templates/dockerManager/viewContainer.html index 3baa62e11..b7bd63db2 100644 --- a/dockerManager/templates/dockerManager/viewContainer.html +++ b/dockerManager/templates/dockerManager/viewContainer.html @@ -210,21 +210,21 @@
    - +
    {% for env, value in envList.items %} - + - + {% endfor %} - +
    - +
    - +
    - +

    + + + {% for key, value in volList.items %} + + + + + {% endfor %} + +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    + +
    + +

    diff --git a/dockerManager/views.py b/dockerManager/views.py index 0fbfebd16..fed61d06b 100644 --- a/dockerManager/views.py +++ b/dockerManager/views.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals from django.shortcuts import render, redirect, HttpResponse from loginSystem.models import Administrator from loginSystem.views import loadLoginPage -from plogical.container import ContainerManager +from .container import ContainerManager from decorators import preDockerRun from plogical.acl import ACLManager import json diff --git a/install/install.py b/install/install.py index 046b090aa..6c4ed0d34 100644 --- a/install/install.py +++ b/install/install.py @@ -780,7 +780,7 @@ class preFlightsChecks: os.chdir(self.path) - command = "wget http://cyberpanel.sh/CyberPanel.1.7.7.tar.gz" + command = "wget http://cyberpanel.sh/CyberPanel.1.8.0.tar.gz" #command = "wget http://cyberpanel.sh/CyberPanelTemp.tar.gz" preFlightsChecks.call(command, self.distro, '[download_install_CyberPanel]', 'CyberPanel Download', @@ -789,7 +789,7 @@ class preFlightsChecks: ## count = 0 - command = "tar zxf CyberPanel.1.7.7.tar.gz" + command = "tar zxf CyberPanel.1.8.0.tar.gz" #command = "tar zxf CyberPanelTemp.tar.gz" preFlightsChecks.call(command, self.distro, '[download_install_CyberPanel]', 'Extract CyberPanel',1, 1, os.EX_OSERR) diff --git a/install/litespeed/functions.sh b/install/litespeed/functions.sh index 008ee5323..aa7774ab3 100644 --- a/install/litespeed/functions.sh +++ b/install/litespeed/functions.sh @@ -45,13 +45,13 @@ init() DIR_OWN="nobody:nobody" CONF_OWN="nobody:nobody" - + BUILD_ROOT="$LSWS_HOME/../../../" WHM_CGIDIR="$BUILD_ROOT/usr/local/cpanel/whostmgr/docroot/cgi" if [ -d "$WHM_CGIDIR" ] ; then HOST_PANEL="cpanel" fi - + } license() @@ -59,14 +59,14 @@ license() SUCC=0 TRY=1 while [ $SUCC -eq "0" ]; do - printf "%s" "Do you agree with above license? " + printf "%s" "Do you agree with above license? " YES_NO='Yes' if [ "x$YES_NO" != "xYes" ]; then if [ $TRY -lt 3 ]; then echo "Sorry, wrong answer! Type 'Yes' with capital 'Y', try again!" TRY=`expr $TRY + 1` else - echo "Abort installation!" + echo "Abort installation!" exit 0 fi @@ -114,11 +114,11 @@ install_dir() DEST_RECOM="/opt/lsws" fi WS_USER="nobody" - else + else cat </dev/null 2>&1 lsadm_gid=`grep "^lsadm:" /etc/group | awk -F : '{ print $3; }'` - useradd -g $lsadm_gid -d / -r -s /sbin/nologin lsadm + useradd -g $lsadm_gid -d / -r -s /sbin/nologin lsadm usermod -a -G $WS_GROUP lsadm #1>/dev/null 2>&1 - + } create_lsadm_solaris() { - groupadd lsadm + groupadd lsadm #1>/dev/null 2>&1 lsadm_gid=`grep "^lsadm:" /etc/group | awk -F: '{ print $3; }'` - useradd -g $lsadm_gid -d / -s /bin/false lsadm + useradd -g $lsadm_gid -d / -s /bin/false lsadm usermod -G $WS_GROUP lsadm #1>/dev/null 2>&1 - + } @@ -946,7 +946,7 @@ installation() create_lsadm_freebsd elif [ "x$SYS_NAME" = "xSunOS" ]; then create_lsadm_solaris - fi + fi grep "^lsadm:" /etc/passwd 1>/dev/null 2>&1 if [ $? -eq 0 ]; then CONF_OWN="lsadm:lsadm" @@ -959,33 +959,33 @@ installation() sed "s:%LSWS_CTRL%:$LSWS_HOME/bin/lswsctrl:" "$LSINSTALL_DIR/admin/misc/lsws.rc.in" > "$LSINSTALL_DIR/admin/misc/lsws.rc" sed "s:%LSWS_CTRL%:$LSWS_HOME/bin/lswsctrl:" "$LSINSTALL_DIR/admin/misc/lsws.rc.gentoo.in" > "$LSINSTALL_DIR/admin/misc/lsws.rc.gentoo" sed "s:%LSWS_CTRL%:$LSWS_HOME/bin/lswsctrl:" "$LSINSTALL_DIR/admin/misc/lshttpd.service.in" > "$LSINSTALL_DIR/admin/misc/lshttpd.service" - + if [ -d "$LSWS_HOME/admin/html.$VERSION" ]; then rm -rf "$LSWS_HOME/admin/html.$VERSION" fi - - util_mkdir "$SDIR_OWN" $DIR_MOD admin bin docs fcgi-bin lib logs admin/logs add-ons share admin/fcgi-bin + + util_mkdir "$SDIR_OWN" $DIR_MOD admin bin docs fcgi-bin lib logs admin/logs add-ons share admin/fcgi-bin util_mkdir "$SDIR_OWN" $DIR_MOD admin/html.$VERSION admin/misc - util_mkdir "$CONF_OWN" $SDIR_MOD conf conf/cert conf/templates admin/conf admin/conf/cert admin/tmp phpbuild autoupdate + util_mkdir "$CONF_OWN" $SDIR_MOD conf conf/cert conf/templates admin/conf admin/conf/cert admin/tmp phpbuild autoupdate util_mkdir "$SDIR_OWN" $SDIR_MOD admin/cgid admin/cgid/secret util_mkdir "$CONF_OWN" $DIR_MOD admin/htpasswds chgrp $WS_GROUP $LSWS_HOME/admin/tmp $LSWS_HOME/admin/cgid $LSWS_HOME/admin/htpasswds chmod g+x $LSWS_HOME/admin/tmp $LSWS_HOME/admin/cgid $LSWS_HOME/admin/htpasswds chown $CONF_OWN $LSWS_HOME/admin/tmp/sess_* 1>/dev/null 2>&1 - util_mkdir "$SDIR_OWN" $DIR_MOD DEFAULT + util_mkdir "$SDIR_OWN" $DIR_MOD DEFAULT buildAdminSslCert - + find "$LSWS_HOME/admin/tmp" -type s -atime +1 -delete 2>/dev/null if [ $? -ne 0 ]; then find "$LSWS_HOME/admin/tmp" -type s -atime +1 2>/dev/null | xargs rm -f - fi + fi find "/tmp/lshttpd" -type s -atime +1 -delete 2>/dev/null if [ $? -ne 0 ]; then find "/tmp/lshttpd" -type s -atime +1 2>/dev/null | xargs rm -f - fi + fi if [ "x$HOST_PANEL" = "xcpanel" ]; then if [ ! -d "$BUILD_ROOT/usr/local/lib/php/autoindex/" ]; then @@ -1012,21 +1012,21 @@ installation() fi util_cpdir "$SDIR_OWN" $DOC_MOD add-ons util_cpfile "$SDIR_OWN" $EXEC_MOD add-ons/modsec/inspectmulti.sh - - util_ccpfile "$SDIR_OWN" $EXEC_MOD fcgi-bin/lsperld.fpl + + util_ccpfile "$SDIR_OWN" $EXEC_MOD fcgi-bin/lsperld.fpl util_cpfile "$SDIR_OWN" $EXEC_MOD fcgi-bin/RackRunner.rb fcgi-bin/RailsRunner.rb fcgi-bin/RailsRunner.rb.2.3 - util_cpfile "$SDIR_OWN" $EXEC_MOD admin/fcgi-bin/admin_php5 - util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/rc-inst.sh admin/misc/admpass.sh admin/misc/rc-uninst.sh admin/misc/uninstall.sh + util_cpfile "$SDIR_OWN" $EXEC_MOD admin/fcgi-bin/admin_php5 + util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/rc-inst.sh admin/misc/admpass.sh admin/misc/rc-uninst.sh admin/misc/uninstall.sh util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/lsws.rc admin/misc/lshttpd.service admin/misc/lsws.rc.gentoo admin/misc/enable_ruby_python_selector.sh - util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/mgr_ver.sh admin/misc/gzipStatic.sh admin/misc/fp_install.sh - util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/create_admin_keypair.sh admin/misc/awstats_install.sh admin/misc/update.sh - util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/cleancache.sh admin/misc/cleanlitemage.sh admin/misc/lsup5.sh + util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/mgr_ver.sh admin/misc/gzipStatic.sh admin/misc/fp_install.sh + util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/create_admin_keypair.sh admin/misc/awstats_install.sh admin/misc/update.sh + util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/cleancache.sh admin/misc/cleanlitemage.sh admin/misc/lsup5.sh util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/fix_cagefs.sh admin/misc/cp_switch_ws.sh util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/lscmctl ln -sf ./lsup5.sh "$LSWS_HOME/admin/misc/lsup.sh" util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/ap_lsws.sh.in admin/misc/build_ap_wrapper.sh admin/misc/cpanel_restart_httpd.in util_cpfile "$SDIR_OWN" $DOC_MOD admin/misc/gdb-bt admin/misc/htpasswd.php admin/misc/php.ini admin/misc/genjCryptionKeyPair.php admin/misc/purge_cache_byurl.php - + if [ -f "$LSINSTALL_DIR/admin/misc/chroot.sh" ]; then util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/chroot.sh fi @@ -1043,7 +1043,7 @@ installation() chown $CONF_OWN "$LSWS_HOME/admin/htpasswds/status" chgrp $WS_GROUP "$LSWS_HOME/admin/htpasswds/status" chmod 0640 "$LSWS_HOME/admin/htpasswds/status" - + if [ $INSTALL_TYPE = "upgrade" ]; then util_ccpfile "$CONF_OWN" $CONF_MOD admin/conf/admin_config.xml util_cpfile "$CONF_OWN" $CONF_MOD admin/conf/php.ini @@ -1067,7 +1067,7 @@ installation() fi if [ ! -f "$LSWS_HOME/DEFAULT/conf/vhconf.xml" ]; then - util_mkdir "$CONF_OWN" $DIR_MOD DEFAULT/conf + util_mkdir "$CONF_OWN" $DIR_MOD DEFAULT/conf util_cpdir "$CONF_OWN" $DOC_MOD DEFAULT/conf fi else @@ -1077,7 +1077,7 @@ installation() util_cpfile "$CONF_OWN" $CONF_MOD conf/httpd_config.xml conf/mime.properties util_mkdir "$CONF_OWN" $DIR_MOD DEFAULT/conf util_cpdir "$CONF_OWN" $DOC_MOD DEFAULT/conf - util_mkdir "$SDIR_OWN" $DIR_MOD DEFAULT/html DEFAULT/cgi-bin + util_mkdir "$SDIR_OWN" $DIR_MOD DEFAULT/html DEFAULT/cgi-bin util_cpdir "$SDIR_OWN" $DOC_MOD DEFAULT/html DEFAULT/cgi-bin fi if [ $SETUP_PHP -eq 1 ]; then @@ -1110,26 +1110,26 @@ installation() util_cpfile "$SDIR_OWN" $EXEC_MOD bin/wswatch.sh - util_cpfilev "$SDIR_OWN" $EXEC_MOD $VERSION bin/lswsctrl bin/lshttpd bin/lscgid + util_cpfilev "$SDIR_OWN" $EXEC_MOD $VERSION bin/lswsctrl bin/lshttpd bin/lscgid $TEST_BIN ! -L "$LSWS_HOME/modules" if [ $? -eq 0 ]; then mv -f "$LSWS_HOME/modules" "$LSWS_HOME/modules.old" fi - + if [ -d "$LSWS_HOME/modules.$VERSION" ]; then rm -rf "$LSWS_HOME/modules.$VERSION" fi util_mkdir "$SDIR_OWN" $DIR_MOD modules.$VERSION - util_cpdirv "$SDIR_OWN" $EXEC_MOD $VERSION modules - + util_cpdirv "$SDIR_OWN" $EXEC_MOD $VERSION modules + #if [ -e "$LSINSTALL_DIR/bin/lshttpd.dbg" ]; then # if [ -f "$LSINSTALL_DIR/bin/lshttpd.dbg.$VERSION" ]; then # rm "$LSINSTALL_DIR/bin/lshttpd.dbg.$VERSION" # fi # util_cpfilev "$SDIR_OWN" $EXEC_MOD $VERSION bin/lshttpd.dbg - # + # # #enable debug build for beta release # ln -sf ./lshttpd.dbg.$VERSION $LSWS_HOME/bin/lshttpd #fi @@ -1141,10 +1141,10 @@ installation() if [ $INST_USER = "root" ]; then chmod u+s "$LSWS_HOME/bin/lscgid.$VERSION" - fi + fi util_cpdir "$SDIR_OWN" $DOC_MOD docs/ - util_cpfile "$SDIR_OWN" $DOC_MOD VERSION BUILD LICENSE* + util_cpfile "$SDIR_OWN" $DOC_MOD VERSION BUILD LICENSE* if [ -f $LSWS_HOME/autoupdate/download ]; then rm $LSWS_HOME/autoupdate/download @@ -1158,12 +1158,12 @@ installation() chown "$CONF_OWN" "$LSWS_HOME/admin/conf/jcryption_keypair" chmod 0600 "$LSWS_HOME/admin/conf/jcryption_keypair" - fix_cloudlinux - + fix_cloudlinux + if [ $INST_USER = "root" ]; then $LSWS_HOME/admin/misc/rc-inst.sh - fi - + fi + } @@ -1179,7 +1179,7 @@ PHP scripts by caching them in compiled state, the overhead of compiling PHP is avoided. Note: If an opcode cache has been installed already, you do not need to - change it. If you need to built PHP binary by yourself, you need to + change it. If you need to built PHP binary by yourself, you need to built PHP opcode cache from source as well, unless the version of your PHP binary is same as that the pre-built PHP opcode cache built for. @@ -1205,8 +1205,8 @@ installAWStats() AWStats Integration -AWStats is a popular log analyzer that generates advanced web server -statistics. LiteSpeed web server seamlessly integrates AWStats into +AWStats is a popular log analyzer that generates advanced web server +statistics. LiteSpeed web server seamlessly integrates AWStats into its Web Admin Interface. AWStats configuration and statistics update have been taken care of by LiteSpeed web server. @@ -1238,23 +1238,23 @@ Congratulations! The LiteSpeed Web Server has been successfully installed. Command line script - "$LSWS_HOME/bin/lswsctrl" can be used to start or stop the server. -It is recommended to limit access to the web administration interface. +It is recommended to limit access to the web administration interface. Right now the interface can be accessed from anywhere where this -machine can be reached over the network. +machine can be reached over the network. Three options are available: - 1. If the interface needs to be accessed only from this machine, just - change the listener for the interface to only listen on the loopback - interface - localhost(127.0.0.1). - 2. If the interface needs to be accessible from limited IP addresses or sub + 1. If the interface needs to be accessed only from this machine, just + change the listener for the interface to only listen on the loopback + interface - localhost(127.0.0.1). + 2. If the interface needs to be accessible from limited IP addresses or sub networks, then set up access control rules for the interface accordingly. - 3. If the interface has to be accessible via internet, SSL (Secure Sockets + 3. If the interface has to be accessible via internet, SSL (Secure Sockets Layer) should be used. Please read respective HOW-TOs on SSL configuration. -To change configurations of the interface, login and click +To change configurations of the interface, login and click "Interface Configuration" button on the main page. The administration interface is located at http://localhost:/ -or http://:/ +or http://:/ EOF @@ -1262,7 +1262,7 @@ EOF if [ $INSTALL_TYPE != "upgrade" ]; then printf "%s\n%s" "Would you like to have LiteSpeed Web Server started automatically" "when the server restarts [Y/n]? " START_SERVER='y' - echo + echo if [ "x$START_SERVER" = "x" ]; then START_SERVER=y @@ -1271,7 +1271,7 @@ EOF $LSWS_HOME/admin/misc/rc-inst.sh else cat <
    -

    CyberPanel v 1.7

    +

    CyberPanel v 1.8

    Web Hosting Control Panel

      diff --git a/loginSystem/views.py b/loginSystem/views.py index 5785f7704..d962020ab 100644 --- a/loginSystem/views.py +++ b/loginSystem/views.py @@ -156,7 +156,7 @@ def loadLoginPage(request): firstName="Cyber",lastName="Panel", acl=acl, token=token) admin.save() - vers = version(currentVersion="1.7", build=7) + vers = version(currentVersion="1.8", build=0) vers.save() package = Package(admin=admin, packageName="Default", diskSpace=1000, diff --git a/plogical/httpProc.py b/plogical/httpProc.py index f68678338..2a338664f 100644 --- a/plogical/httpProc.py +++ b/plogical/httpProc.py @@ -14,10 +14,12 @@ class httpProc: return render(self.request, self.templateName) else: return render(self.request, self.templateName, self.data) + def ajaxPre(self, status, errorMessage, success = None): final_dic = {'status': status, 'error_message': errorMessage, 'success': success} final_json = json.dumps(final_dic) return HttpResponse(final_json) + def ajax(self, status, errorMessage, data = None): if data == None: finalDic = {'status': status, 'error_message': errorMessage} @@ -34,3 +36,9 @@ class httpProc: finalJson = json.dumps(finalDic) return HttpResponse(finalJson) + @staticmethod + def AJAX(status, errorMessage, success = None): + final_dic = {'status': status, 'error_message': errorMessage, 'success': success} + final_json = json.dumps(final_dic) + return HttpResponse(final_json) + diff --git a/plogical/processUtilities.py b/plogical/processUtilities.py index 1a4d1b642..6176c7b94 100644 --- a/plogical/processUtilities.py +++ b/plogical/processUtilities.py @@ -114,5 +114,17 @@ class ProcessUtilities: else: return ProcessUtilities.centos + @staticmethod + def containerCheck(): + try: + command = 'sudo cat /etc/cgrules.conf' + result = subprocess.call(shlex.split(command)) + if result == 1: + return 0 + else: + return 1 + except BaseException: + return 0 + diff --git a/plogical/upgrade.py b/plogical/upgrade.py index 1850603ba..843e9ade9 100644 --- a/plogical/upgrade.py +++ b/plogical/upgrade.py @@ -410,6 +410,77 @@ WantedBy=multi-user.target""" CONSTRAINT `s3Backups_backuplogs_owner_id_c7cb5872_fk_s3Backups` FOREIGN KEY (`owner_id`) REFERENCES `s3Backups_backupplando` (`id`) )""" + try: + cursor.execute(query) + except: + pass + + ## + + query = """CREATE TABLE `s3Backups_minionodes` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `endPointURL` varchar(200) NOT NULL, + `accessKey` varchar(200) NOT NULL, + `secretKey` varchar(200) NOT NULL, + `owner_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `endPointURL` (`endPointURL`), + UNIQUE KEY `accessKey` (`accessKey`), + KEY `s3Backups_minionodes_owner_id_e50993d9_fk_loginSyst` (`owner_id`), + CONSTRAINT `s3Backups_minionodes_owner_id_e50993d9_fk_loginSyst` FOREIGN KEY (`owner_id`) REFERENCES `loginSystem_administrator` (`id`) +)""" + + try: + cursor.execute(query) + except: + pass + + query = """CREATE TABLE `s3Backups_backupplanminio` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL, + `freq` varchar(50) NOT NULL, + `retention` int(11) NOT NULL, + `lastRun` varchar(50) NOT NULL, + `minioNode_id` int(11) NOT NULL, + `owner_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `name` (`name`), + KEY `s3Backups_backupplan_minioNode_id_a4eaf917_fk_s3Backups` (`minioNode_id`), + KEY `s3Backups_backupplan_owner_id_d6830e67_fk_loginSyst` (`owner_id`), + CONSTRAINT `s3Backups_backupplan_minioNode_id_a4eaf917_fk_s3Backups` FOREIGN KEY (`minioNode_id`) REFERENCES `s3Backups_minionodes` (`id`), + CONSTRAINT `s3Backups_backupplan_owner_id_d6830e67_fk_loginSyst` FOREIGN KEY (`owner_id`) REFERENCES `loginSystem_administrator` (`id`) +)""" + + try: + cursor.execute(query) + except: + pass + + query = """CREATE TABLE `s3Backups_websitesinplanminio` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `domain` varchar(100) NOT NULL, + `owner_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `s3Backups_websitesin_owner_id_224ce049_fk_s3Backups` (`owner_id`), + CONSTRAINT `s3Backups_websitesin_owner_id_224ce049_fk_s3Backups` FOREIGN KEY (`owner_id`) REFERENCES `s3Backups_backupplanminio` (`id`) +)""" + + try: + cursor.execute(query) + except: + pass + + query = """CREATE TABLE `s3Backups_backuplogsminio` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `timeStamp` varchar(200) NOT NULL, + `level` varchar(5) NOT NULL, + `msg` varchar(500) NOT NULL, + `owner_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `s3Backups_backuplogs_owner_id_f19e1736_fk_s3Backups` (`owner_id`), + CONSTRAINT `s3Backups_backuplogs_owner_id_f19e1736_fk_s3Backups` FOREIGN KEY (`owner_id`) REFERENCES `s3Backups_backupplanminio` (`id`) +)""" + try: cursor.execute(query) except: @@ -633,6 +704,37 @@ WantedBy=multi-user.target""" except: pass + @staticmethod + def containerMigrations(): + try: + connection, cursor = Upgrade.setupConnection('cyberpanel') + + query = """CREATE TABLE `containerization_containerlimits` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `cpuPers` varchar(10) NOT NULL, + `IO` varchar(10) NOT NULL, + `IOPS` varchar(10) NOT NULL, + `memory` varchar(10) NOT NULL, + `networkSpeed` varchar(10) NOT NULL, + `networkHexValue` varchar(10) NOT NULL, + `enforce` int(11) NOT NULL, + `owner_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `containerization_con_owner_id_494eb637_fk_websiteFu` (`owner_id`), + CONSTRAINT `containerization_con_owner_id_494eb637_fk_websiteFu` FOREIGN KEY (`owner_id`) REFERENCES `websiteFunctions_websites` (`id`) +)""" + try: + cursor.execute(query) + except: + pass + + try: + connection.close() + except: + pass + except: + pass + @staticmethod def enableServices(): try: @@ -705,6 +807,11 @@ WantedBy=multi-user.target""" if items.find('dockerManager') > -1: dockerManager = 0 + containerization = 1 + for items in data: + if items.find('containerization') > -1: + containerization = 0 + Upgrade.stdOut('Restoring settings file!') @@ -724,6 +831,10 @@ WantedBy=multi-user.target""" writeToFile.writelines(" 's3Backups',\n") if dockerManager == 1: writeToFile.writelines(" 'dockerManager',\n") + + if containerization == 1: + writeToFile.writelines(" 'containerization',\n") + else: writeToFile.writelines(items) @@ -906,6 +1017,7 @@ WantedBy=multi-user.target""" Upgrade.applyLoginSystemMigrations() Upgrade.s3BackupMigrations() + Upgrade.containerMigrations() Upgrade.enableServices() Upgrade.installPHP73() diff --git a/s3Backups/s3Backups.py b/s3Backups/s3Backups.py index df584cea2..530eafb47 100644 --- a/s3Backups/s3Backups.py +++ b/s3Backups/s3Backups.py @@ -9,7 +9,6 @@ try: import threading as multi from plogical.mailUtilities import mailUtilities import boto3 - from minio.error import ResponseError from boto3.s3.transfer import TransferConfig import json from .models import * @@ -148,6 +147,17 @@ class S3Backups(multi.Thread): proc = httpProc(self.request, None, None) return proc.ajax(0, str(msg)) + def fetchAWSKeys(self): + path = '/home/cyberpanel/.aws' + credentials = path + '/credentials' + + data = open(credentials, 'r').readlines() + + aws_access_key_id = data[1].split(' ')[2].strip(' ').strip('\n') + aws_secret_access_key = data[2].split(' ')[2].strip(' ').strip('\n') + + return aws_access_key_id, aws_secret_access_key + def fetchBuckets(self): try: @@ -159,7 +169,15 @@ class S3Backups(multi.Thread): if currentACL['admin'] == 0: return proc.ajax(0, 'Only administrators can use AWS S3 Backups.') - s3 = boto3.resource('s3') + + aws_access_key_id, aws_secret_access_key = self.fetchAWSKeys() + + s3 = boto3.resource( + 's3', + aws_access_key_id = aws_access_key_id, + aws_secret_access_key = aws_secret_access_key + ) + json_data = "[" checker = 0 @@ -404,7 +422,16 @@ class S3Backups(multi.Thread): plan = BackupPlan.objects.get(name=self.data['planName']) bucketName = plan.bucket.strip('\n').strip(' ') runTime = time.strftime("%d:%m:%Y") - client = boto3.client('s3') + + aws_access_key_id, aws_secret_access_key = self.fetchAWSKeys() + + client = boto3.client( + 's3', + aws_access_key_id = aws_access_key_id, + aws_secret_access_key = aws_secret_access_key + ) + + config = TransferConfig(multipart_threshold=1024 * 25, max_concurrency=10, multipart_chunksize=1024 * 25, use_threads=True) diff --git a/serverStatus/litespeed/functions.sh b/serverStatus/litespeed/functions.sh index 86c601dc2..aa7774ab3 100644 --- a/serverStatus/litespeed/functions.sh +++ b/serverStatus/litespeed/functions.sh @@ -41,17 +41,17 @@ init() PHP_SUEXEC=2 WS_USER=nobody - WS_GROUP=nogroup + WS_GROUP=nobody DIR_OWN="nobody:nobody" CONF_OWN="nobody:nobody" - + BUILD_ROOT="$LSWS_HOME/../../../" WHM_CGIDIR="$BUILD_ROOT/usr/local/cpanel/whostmgr/docroot/cgi" if [ -d "$WHM_CGIDIR" ] ; then HOST_PANEL="cpanel" fi - + } license() @@ -59,14 +59,14 @@ license() SUCC=0 TRY=1 while [ $SUCC -eq "0" ]; do - printf "%s" "Do you agree with above license? " + printf "%s" "Do you agree with above license? " YES_NO='Yes' if [ "x$YES_NO" != "xYes" ]; then if [ $TRY -lt 3 ]; then echo "Sorry, wrong answer! Type 'Yes' with capital 'Y', try again!" TRY=`expr $TRY + 1` else - echo "Abort installation!" + echo "Abort installation!" exit 0 fi @@ -114,11 +114,11 @@ install_dir() DEST_RECOM="/opt/lsws" fi WS_USER="nobody" - else + else cat </dev/null 2>&1 lsadm_gid=`grep "^lsadm:" /etc/group | awk -F : '{ print $3; }'` - useradd -g $lsadm_gid -d / -r -s /sbin/nologin lsadm + useradd -g $lsadm_gid -d / -r -s /sbin/nologin lsadm usermod -a -G $WS_GROUP lsadm #1>/dev/null 2>&1 - + } create_lsadm_solaris() { - groupadd lsadm + groupadd lsadm #1>/dev/null 2>&1 lsadm_gid=`grep "^lsadm:" /etc/group | awk -F: '{ print $3; }'` - useradd -g $lsadm_gid -d / -s /bin/false lsadm + useradd -g $lsadm_gid -d / -s /bin/false lsadm usermod -G $WS_GROUP lsadm #1>/dev/null 2>&1 - + } @@ -946,7 +946,7 @@ installation() create_lsadm_freebsd elif [ "x$SYS_NAME" = "xSunOS" ]; then create_lsadm_solaris - fi + fi grep "^lsadm:" /etc/passwd 1>/dev/null 2>&1 if [ $? -eq 0 ]; then CONF_OWN="lsadm:lsadm" @@ -959,33 +959,33 @@ installation() sed "s:%LSWS_CTRL%:$LSWS_HOME/bin/lswsctrl:" "$LSINSTALL_DIR/admin/misc/lsws.rc.in" > "$LSINSTALL_DIR/admin/misc/lsws.rc" sed "s:%LSWS_CTRL%:$LSWS_HOME/bin/lswsctrl:" "$LSINSTALL_DIR/admin/misc/lsws.rc.gentoo.in" > "$LSINSTALL_DIR/admin/misc/lsws.rc.gentoo" sed "s:%LSWS_CTRL%:$LSWS_HOME/bin/lswsctrl:" "$LSINSTALL_DIR/admin/misc/lshttpd.service.in" > "$LSINSTALL_DIR/admin/misc/lshttpd.service" - + if [ -d "$LSWS_HOME/admin/html.$VERSION" ]; then rm -rf "$LSWS_HOME/admin/html.$VERSION" fi - - util_mkdir "$SDIR_OWN" $DIR_MOD admin bin docs fcgi-bin lib logs admin/logs add-ons share admin/fcgi-bin + + util_mkdir "$SDIR_OWN" $DIR_MOD admin bin docs fcgi-bin lib logs admin/logs add-ons share admin/fcgi-bin util_mkdir "$SDIR_OWN" $DIR_MOD admin/html.$VERSION admin/misc - util_mkdir "$CONF_OWN" $SDIR_MOD conf conf/cert conf/templates admin/conf admin/conf/cert admin/tmp phpbuild autoupdate + util_mkdir "$CONF_OWN" $SDIR_MOD conf conf/cert conf/templates admin/conf admin/conf/cert admin/tmp phpbuild autoupdate util_mkdir "$SDIR_OWN" $SDIR_MOD admin/cgid admin/cgid/secret util_mkdir "$CONF_OWN" $DIR_MOD admin/htpasswds chgrp $WS_GROUP $LSWS_HOME/admin/tmp $LSWS_HOME/admin/cgid $LSWS_HOME/admin/htpasswds chmod g+x $LSWS_HOME/admin/tmp $LSWS_HOME/admin/cgid $LSWS_HOME/admin/htpasswds chown $CONF_OWN $LSWS_HOME/admin/tmp/sess_* 1>/dev/null 2>&1 - util_mkdir "$SDIR_OWN" $DIR_MOD DEFAULT + util_mkdir "$SDIR_OWN" $DIR_MOD DEFAULT buildAdminSslCert - + find "$LSWS_HOME/admin/tmp" -type s -atime +1 -delete 2>/dev/null if [ $? -ne 0 ]; then find "$LSWS_HOME/admin/tmp" -type s -atime +1 2>/dev/null | xargs rm -f - fi + fi find "/tmp/lshttpd" -type s -atime +1 -delete 2>/dev/null if [ $? -ne 0 ]; then find "/tmp/lshttpd" -type s -atime +1 2>/dev/null | xargs rm -f - fi + fi if [ "x$HOST_PANEL" = "xcpanel" ]; then if [ ! -d "$BUILD_ROOT/usr/local/lib/php/autoindex/" ]; then @@ -1012,21 +1012,21 @@ installation() fi util_cpdir "$SDIR_OWN" $DOC_MOD add-ons util_cpfile "$SDIR_OWN" $EXEC_MOD add-ons/modsec/inspectmulti.sh - - util_ccpfile "$SDIR_OWN" $EXEC_MOD fcgi-bin/lsperld.fpl + + util_ccpfile "$SDIR_OWN" $EXEC_MOD fcgi-bin/lsperld.fpl util_cpfile "$SDIR_OWN" $EXEC_MOD fcgi-bin/RackRunner.rb fcgi-bin/RailsRunner.rb fcgi-bin/RailsRunner.rb.2.3 - util_cpfile "$SDIR_OWN" $EXEC_MOD admin/fcgi-bin/admin_php5 - util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/rc-inst.sh admin/misc/admpass.sh admin/misc/rc-uninst.sh admin/misc/uninstall.sh + util_cpfile "$SDIR_OWN" $EXEC_MOD admin/fcgi-bin/admin_php5 + util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/rc-inst.sh admin/misc/admpass.sh admin/misc/rc-uninst.sh admin/misc/uninstall.sh util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/lsws.rc admin/misc/lshttpd.service admin/misc/lsws.rc.gentoo admin/misc/enable_ruby_python_selector.sh - util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/mgr_ver.sh admin/misc/gzipStatic.sh admin/misc/fp_install.sh - util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/create_admin_keypair.sh admin/misc/awstats_install.sh admin/misc/update.sh - util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/cleancache.sh admin/misc/cleanlitemage.sh admin/misc/lsup5.sh + util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/mgr_ver.sh admin/misc/gzipStatic.sh admin/misc/fp_install.sh + util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/create_admin_keypair.sh admin/misc/awstats_install.sh admin/misc/update.sh + util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/cleancache.sh admin/misc/cleanlitemage.sh admin/misc/lsup5.sh util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/fix_cagefs.sh admin/misc/cp_switch_ws.sh util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/lscmctl ln -sf ./lsup5.sh "$LSWS_HOME/admin/misc/lsup.sh" util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/ap_lsws.sh.in admin/misc/build_ap_wrapper.sh admin/misc/cpanel_restart_httpd.in util_cpfile "$SDIR_OWN" $DOC_MOD admin/misc/gdb-bt admin/misc/htpasswd.php admin/misc/php.ini admin/misc/genjCryptionKeyPair.php admin/misc/purge_cache_byurl.php - + if [ -f "$LSINSTALL_DIR/admin/misc/chroot.sh" ]; then util_cpfile "$SDIR_OWN" $EXEC_MOD admin/misc/chroot.sh fi @@ -1043,7 +1043,7 @@ installation() chown $CONF_OWN "$LSWS_HOME/admin/htpasswds/status" chgrp $WS_GROUP "$LSWS_HOME/admin/htpasswds/status" chmod 0640 "$LSWS_HOME/admin/htpasswds/status" - + if [ $INSTALL_TYPE = "upgrade" ]; then util_ccpfile "$CONF_OWN" $CONF_MOD admin/conf/admin_config.xml util_cpfile "$CONF_OWN" $CONF_MOD admin/conf/php.ini @@ -1067,7 +1067,7 @@ installation() fi if [ ! -f "$LSWS_HOME/DEFAULT/conf/vhconf.xml" ]; then - util_mkdir "$CONF_OWN" $DIR_MOD DEFAULT/conf + util_mkdir "$CONF_OWN" $DIR_MOD DEFAULT/conf util_cpdir "$CONF_OWN" $DOC_MOD DEFAULT/conf fi else @@ -1077,7 +1077,7 @@ installation() util_cpfile "$CONF_OWN" $CONF_MOD conf/httpd_config.xml conf/mime.properties util_mkdir "$CONF_OWN" $DIR_MOD DEFAULT/conf util_cpdir "$CONF_OWN" $DOC_MOD DEFAULT/conf - util_mkdir "$SDIR_OWN" $DIR_MOD DEFAULT/html DEFAULT/cgi-bin + util_mkdir "$SDIR_OWN" $DIR_MOD DEFAULT/html DEFAULT/cgi-bin util_cpdir "$SDIR_OWN" $DOC_MOD DEFAULT/html DEFAULT/cgi-bin fi if [ $SETUP_PHP -eq 1 ]; then @@ -1110,26 +1110,26 @@ installation() util_cpfile "$SDIR_OWN" $EXEC_MOD bin/wswatch.sh - util_cpfilev "$SDIR_OWN" $EXEC_MOD $VERSION bin/lswsctrl bin/lshttpd bin/lscgid + util_cpfilev "$SDIR_OWN" $EXEC_MOD $VERSION bin/lswsctrl bin/lshttpd bin/lscgid $TEST_BIN ! -L "$LSWS_HOME/modules" if [ $? -eq 0 ]; then mv -f "$LSWS_HOME/modules" "$LSWS_HOME/modules.old" fi - + if [ -d "$LSWS_HOME/modules.$VERSION" ]; then rm -rf "$LSWS_HOME/modules.$VERSION" fi util_mkdir "$SDIR_OWN" $DIR_MOD modules.$VERSION - util_cpdirv "$SDIR_OWN" $EXEC_MOD $VERSION modules - + util_cpdirv "$SDIR_OWN" $EXEC_MOD $VERSION modules + #if [ -e "$LSINSTALL_DIR/bin/lshttpd.dbg" ]; then # if [ -f "$LSINSTALL_DIR/bin/lshttpd.dbg.$VERSION" ]; then # rm "$LSINSTALL_DIR/bin/lshttpd.dbg.$VERSION" # fi # util_cpfilev "$SDIR_OWN" $EXEC_MOD $VERSION bin/lshttpd.dbg - # + # # #enable debug build for beta release # ln -sf ./lshttpd.dbg.$VERSION $LSWS_HOME/bin/lshttpd #fi @@ -1141,10 +1141,10 @@ installation() if [ $INST_USER = "root" ]; then chmod u+s "$LSWS_HOME/bin/lscgid.$VERSION" - fi + fi util_cpdir "$SDIR_OWN" $DOC_MOD docs/ - util_cpfile "$SDIR_OWN" $DOC_MOD VERSION BUILD LICENSE* + util_cpfile "$SDIR_OWN" $DOC_MOD VERSION BUILD LICENSE* if [ -f $LSWS_HOME/autoupdate/download ]; then rm $LSWS_HOME/autoupdate/download @@ -1158,12 +1158,12 @@ installation() chown "$CONF_OWN" "$LSWS_HOME/admin/conf/jcryption_keypair" chmod 0600 "$LSWS_HOME/admin/conf/jcryption_keypair" - fix_cloudlinux - + fix_cloudlinux + if [ $INST_USER = "root" ]; then $LSWS_HOME/admin/misc/rc-inst.sh - fi - + fi + } @@ -1179,7 +1179,7 @@ PHP scripts by caching them in compiled state, the overhead of compiling PHP is avoided. Note: If an opcode cache has been installed already, you do not need to - change it. If you need to built PHP binary by yourself, you need to + change it. If you need to built PHP binary by yourself, you need to built PHP opcode cache from source as well, unless the version of your PHP binary is same as that the pre-built PHP opcode cache built for. @@ -1205,8 +1205,8 @@ installAWStats() AWStats Integration -AWStats is a popular log analyzer that generates advanced web server -statistics. LiteSpeed web server seamlessly integrates AWStats into +AWStats is a popular log analyzer that generates advanced web server +statistics. LiteSpeed web server seamlessly integrates AWStats into its Web Admin Interface. AWStats configuration and statistics update have been taken care of by LiteSpeed web server. @@ -1238,23 +1238,23 @@ Congratulations! The LiteSpeed Web Server has been successfully installed. Command line script - "$LSWS_HOME/bin/lswsctrl" can be used to start or stop the server. -It is recommended to limit access to the web administration interface. +It is recommended to limit access to the web administration interface. Right now the interface can be accessed from anywhere where this -machine can be reached over the network. +machine can be reached over the network. Three options are available: - 1. If the interface needs to be accessed only from this machine, just - change the listener for the interface to only listen on the loopback - interface - localhost(127.0.0.1). - 2. If the interface needs to be accessible from limited IP addresses or sub + 1. If the interface needs to be accessed only from this machine, just + change the listener for the interface to only listen on the loopback + interface - localhost(127.0.0.1). + 2. If the interface needs to be accessible from limited IP addresses or sub networks, then set up access control rules for the interface accordingly. - 3. If the interface has to be accessible via internet, SSL (Secure Sockets + 3. If the interface has to be accessible via internet, SSL (Secure Sockets Layer) should be used. Please read respective HOW-TOs on SSL configuration. -To change configurations of the interface, login and click +To change configurations of the interface, login and click "Interface Configuration" button on the main page. The administration interface is located at http://localhost:/ -or http://:/ +or http://:/ EOF @@ -1262,7 +1262,7 @@ EOF if [ $INSTALL_TYPE != "upgrade" ]; then printf "%s\n%s" "Would you like to have LiteSpeed Web Server started automatically" "when the server restarts [Y/n]? " START_SERVER='y' - echo + echo if [ "x$START_SERVER" = "x" ]; then START_SERVER=y @@ -1271,7 +1271,7 @@ EOF $LSWS_HOME/admin/misc/rc-inst.sh else cat <
      - -
      @@ -165,7 +163,6 @@
      -