Files
CyberPanel/plogical/container.py

1078 lines
41 KiB
Python
Raw Normal View History

2019-01-07 13:11:12 +00:00
#!/usr/local/CyberCP/bin/python2
from __future__ import division
import os
import os.path
import sys
import django
import mimetypes
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
sys.path.append('/usr/local/CyberCP')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings")
django.setup()
import json
from acl import ACLManager
import CyberCPLogFileWriter as logging
from django.shortcuts import HttpResponse, render
from loginSystem.models import Administrator, ACL
import subprocess
import shlex
import time
from dockerManager.models import Containers
from math import ceil
import docker
import docker.utils
import requests
2019-01-09 14:55:10 +05:00
from processUtilities import ProcessUtilities
from serverStatus.serverStatusUtil import ServerStatusUtil
import threading as multi
2019-01-12 17:52:45 +05:00
from mailUtilities import mailUtilities
2019-01-07 13:11:12 +00:00
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
# Use default socket to connect
2019-01-09 14:55:10 +05:00
class ContainerManager(multi.Thread):
def __init__(self, name=None, function=None):
multi.Thread.__init__(self)
2019-01-07 13:11:12 +00:00
self.name = name
2019-01-09 14:55:10 +05:00
self.function = function
2019-01-08 22:38:33 +05:00
2019-01-09 14:55:10 +05:00
def run(self):
2019-01-07 13:11:12 +00:00
try:
2019-01-09 14:55:10 +05:00
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)
2019-01-07 13:11:12 +00:00
if ACLManager.currentContextPermission(currentACL, 'createContainer') == 0:
return ACLManager.loadError()
2019-01-08 22:38:33 +05:00
2019-01-12 17:52:45 +05:00
mailUtilities.checkHome()
2019-01-09 14:55:10 +05:00
statusFile = open(ServerStatusUtil.lswsInstallStatusPath, 'w')
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,
"Starting Docker Installation..\n", 1)
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
2019-01-08 22:38:33 +05:00
2019-01-08 12:30:13 +00:00
command = 'sudo groupadd docker'
2019-01-09 14:55:10 +05:00
ServerStatusUtil.executioner(command, statusFile)
2019-01-08 22:38:33 +05:00
2019-01-08 12:30:13 +00:00
command = 'sudo usermod -aG docker cyberpanel'
2019-01-09 14:55:10 +05:00
ServerStatusUtil.executioner(command, statusFile)
2019-01-08 22:38:33 +05:00
2019-01-09 14:55:10 +05:00
command = 'sudo systemctl enable docker'
ServerStatusUtil.executioner(command, statusFile)
2019-01-08 22:38:33 +05:00
2019-01-09 14:55:10 +05:00
command = 'sudo systemctl start docker'
ServerStatusUtil.executioner(command, statusFile)
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath,
"Docker successfully installed.[200]\n", 1)
2019-01-07 13:11:12 +00:00
2019-01-12 17:52:45 +05:00
time.sleep(2)
cm = ContainerManager(self.name, 'restartGunicorn')
cm.start()
2019-01-07 13:11:12 +00:00
except BaseException, msg:
2019-01-09 14:55:10 +05:00
logging.CyberCPLogFileWriter.statusWriter(ServerStatusUtil.lswsInstallStatusPath, str(msg) + ' [404].', 1)
2019-01-08 22:38:33 +05:00
def createContainer(self, request=None, userID=None, data=None):
try:
2019-01-08 12:30:13 +00:00
admin = Administrator.objects.get(pk=userID)
if admin.acl.adminStatus != 1:
2019-01-07 13:11:12 +00:00
return ACLManager.loadError()
2019-01-08 22:38:33 +05:00
2019-01-08 12:30:13 +00:00
client = docker.from_env()
dockerAPI = docker.APIClient()
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
adminNames = ACLManager.loadAllUsers(userID)
tag = request.GET.get('tag')
image = request.GET.get('image')
tag = tag.split(" (")[0]
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
if "/" in image:
name = image.split("/")[0] + "." + image.split("/")[1]
else:
name = image
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
try:
2019-01-08 22:38:33 +05:00
inspectImage = dockerAPI.inspect_image(image + ":" + tag)
2019-01-07 13:11:12 +00:00
except docker.errors.ImageNotFound:
val = request.session['userID']
admin = Administrator.objects.get(pk=val)
2019-01-08 22:38:33 +05:00
return render(request, 'dockerManager/images.html', {"type": admin.type,
'image': image,
'tag': tag})
2019-01-07 13:11:12 +00:00
envList = {};
if 'Env' in inspectImage['Config']:
for item in inspectImage['Config']['Env']:
if '=' in item:
2019-01-08 22:38:33 +05:00
splitedItem = item.split('=', 1)
2019-01-07 13:11:12 +00:00
print splitedItem
envList[splitedItem[0]] = splitedItem[1]
else:
envList[item] = ""
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
portConfig = {};
if 'ExposedPorts' in inspectImage['Config']:
for item in inspectImage['Config']['ExposedPorts']:
portDef = item.split('/')
2019-01-08 22:38:33 +05:00
portConfig[portDef[0]] = portDef[1]
2019-01-07 13:11:12 +00:00
if image is None or image is '' or tag is None or tag is '':
return redirect(loadImages)
2019-01-08 22:38:33 +05:00
Data = {"ownerList": adminNames, "image": image, "name": name, "tag": tag, "portConfig": portConfig,
"envList": envList}
2019-01-07 13:11:12 +00:00
return render(request, 'dockerManager/runContainer.html', Data)
except BaseException, msg:
return HttpResponse(str(msg))
2019-01-08 22:38:33 +05:00
def loadContainerHome(self, request=None, userID=None, data=None):
2019-01-07 13:11:12 +00:00
name = self.name
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
if ACLManager.checkContainerOwnership(name, userID) != 1:
return ACLManager.loadError()
2019-01-08 22:38:33 +05:00
2019-01-08 12:30:13 +00:00
client = docker.from_env()
dockerAPI = docker.APIClient()
2019-01-07 13:11:12 +00:00
try:
container = client.containers.get(name)
except docker.errors.NotFound as err:
return HttpResponse("Container not found")
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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)
print data['envList']
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
stats = container.stats(decode=False, stream=False)
logs = container.logs(stream=True)
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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"
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
if 'usage' in stats['memory_stats']:
2019-01-08 22:38:33 +05:00
# Calculate Usage
2019-01-07 13:11:12 +00:00
# Source: https://github.com/docker/docker/blob/28a7577a029780e4533faf3d057ec9f6c7a10948/api/client/stats.go#L309
data['memoryUsage'] = (stats['memory_stats']['usage'] / stats['memory_stats']['limit']) * 100
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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
2019-01-08 22:38:33 +05:00
data['cpuUsage'] = 0
2019-01-07 13:11:12 +00:00
return render(request, 'dockerManager/viewContainer.html', data)
2019-01-08 22:38:33 +05:00
def listContainers(self, request=None, userID=None, data=None):
2019-01-07 13:11:12 +00:00
try:
2019-01-08 12:30:13 +00:00
client = docker.from_env()
dockerAPI = docker.APIClient()
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
currentACL = ACLManager.loadedACL(userID)
containers = ACLManager.findAllContainers(currentACL, userID)
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
allContainers = client.containers.list()
containersList = []
showUnlistedContainer = True
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
# 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)
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
if not unlistedContainers:
showUnlistedContainer = False
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
adminNames = ACLManager.loadAllUsers(userID)
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
pages = float(len(containers)) / float(10)
pagination = []
if pages <= 1.0:
pages = 1
pagination.append('<li><a href="\#"></a></li>')
else:
pages = ceil(pages)
finalPages = int(pages) + 1
for i in range(1, finalPages):
pagination.append('<li><a href="\#">' + str(i) + '</a></li>')
return render(request, 'dockerManager/listContainers.html', {"pagination": pagination,
2019-01-08 22:38:33 +05:00
"unlistedContainers": unlistedContainers,
"adminNames": adminNames,
"showUnlistedContainer": showUnlistedContainer})
2019-01-07 13:11:12 +00:00
except BaseException, msg:
return HttpResponse(str(msg))
2019-01-08 22:38:33 +05:00
def getContainerLogs(self, userID=None, data=None):
2019-01-07 13:11:12 +00:00
try:
name = data['name']
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
# Check if container is registered in database or unlisted
2019-01-08 22:38:33 +05:00
if Containers.objects.filter(name=name).exists():
2019-01-07 13:11:12 +00:00
if ACLManager.checkContainerOwnership(name, userID) != 1:
2019-01-08 22:38:33 +05:00
return ACLManager.loadErrorJson('containerLogStatus', 0)
2019-01-08 12:30:13 +00:00
client = docker.from_env()
2019-01-08 22:38:33 +05:00
dockerAPI = docker.APIClient()
2019-01-07 13:11:12 +00:00
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:
2019-01-08 22:38:33 +05:00
data_ret = {'containerLogStatus': 0, 'containerLog': 'Error', 'error_message': str(msg)}
2019-01-07 13:11:12 +00:00
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
2019-01-08 22:38:33 +05:00
def submitContainerCreation(self, userID=None, data=None):
2019-01-07 13:11:12 +00:00
try:
2019-01-08 12:30:13 +00:00
admin = Administrator.objects.get(pk=userID)
if admin.acl.adminStatus != 1:
2019-01-08 22:38:33 +05:00
return ACLManager.loadErrorJson('createContainerStatus', 0)
2019-01-08 12:30:13 +00:00
client = docker.from_env()
dockerAPI = docker.APIClient()
2019-01-07 13:11:12 +00:00
name = data['name']
image = data['image']
tag = data['tag']
dockerOwner = data['dockerOwner']
memory = data['memory']
envList = data['envList']
2019-01-08 22:38:33 +05:00
inspectImage = dockerAPI.inspect_image(image + ":" + tag)
2019-01-07 13:11:12 +00:00
portConfig = {}
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
# Formatting envList for usage
envDict = {}
for key, value in envList.iteritems():
if (value['name'] != '') or (value['value'] != ''):
envDict[value['name']] = value['value']
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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]
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
## Create Configurations
admin = Administrator.objects.get(userName=dockerOwner)
2019-01-08 22:38:33 +05:00
containerArgs = {'image': image + ":" + tag,
'detach': True,
'name': name,
'ports': portConfig,
2019-01-07 13:11:12 +00:00
'publish_all_ports': True,
2019-01-08 22:38:33 +05:00
'environment': envDict}
containerArgs['mem_limit'] = memory * 1048576; # Converts MB to bytes ( 0 * x = 0 for unlimited memory)
2019-01-07 13:11:12 +00:00
try:
container = client.containers.create(**containerArgs)
except Exception as err:
2019-01-08 22:38:33 +05:00
if "port is already allocated" in err: # We need to delete container if port is not available
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
con = Containers(admin=admin,
2019-01-08 22:38:33 +05:00
name=name,
tag=tag,
image=image,
memory=memory,
ports=json.dumps(portConfig),
env=json.dumps(envDict),
cid=container.id)
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
def submitInstallImage(self, userID=None, data=None):
2019-01-07 13:11:12 +00:00
try:
2019-01-08 12:30:13 +00:00
admin = Administrator.objects.get(pk=userID)
if admin.acl.adminStatus != 1:
2019-01-08 22:38:33 +05:00
return ACLManager.loadErrorJson('installImageStatus', 0)
2019-01-08 12:30:13 +00:00
client = docker.from_env()
dockerAPI = docker.APIClient()
2019-01-07 13:11:12 +00:00
image = data['image']
tag = data['tag']
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
try:
2019-01-08 22:38:33 +05:00
inspectImage = dockerAPI.inspect_image(image + ":" + tag)
2019-01-07 13:11:12 +00:00
data_ret = {'installImageStatus': 0, 'error_message': "Image already installed"}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except docker.errors.ImageNotFound:
pass
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
return HttpResponse(json_data)
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
return HttpResponse(json_data)
def submitContainerDeletion(self, userID=None, data=None, called=False):
2019-01-07 13:11:12 +00:00
try:
name = data['name']
# Check if container is registered in database or unlisted
2019-01-08 22:38:33 +05:00
if Containers.objects.filter(name=name).exists():
2019-01-07 13:11:12 +00:00
if ACLManager.checkContainerOwnership(name, userID) != 1:
if called:
return 'Permission error'
else:
return ACLManager.loadErrorJson('websiteDeleteStatus', 0)
2019-01-08 12:30:13 +00:00
client = docker.from_env()
dockerAPI = docker.APIClient()
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
unlisted = data['unlisted']
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
if 'force' in data:
force = True
else:
force = False
if not unlisted:
containerOBJ = Containers.objects.get(name=name)
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
return HttpResponse(json_data)
2019-01-07 13:11:12 +00:00
try:
2019-01-08 22:38:33 +05:00
container.stop() # Stop container
container.kill() # INCASE graceful stop doesn't work
2019-01-07 13:11:12 +00:00
except:
pass
try:
2019-01-08 22:38:33 +05:00
container.remove() # Finally remove container
2019-01-07 13:11:12 +00:00
except docker.errors.APIError as err:
data_ret = {'delContainerStatus': 0, 'error_message': str(err)}
json_data = json.dumps(data_ret)
2019-01-08 22:38:33 +05:00
return HttpResponse(json_data)
2019-01-07 13:11:12 +00:00
except:
if called:
return "Unknown"
else:
data_ret = {'delContainerStatus': 0, 'error_message': 'Unknown error'}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
if not unlisted and not called:
2019-01-08 22:38:33 +05:00
containerOBJ.delete()
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
def getContainerList(self, userID=None, data=None):
2019-01-07 13:11:12 +00:00
try:
2019-01-08 12:30:13 +00:00
admin = Administrator.objects.get(pk=userID)
if admin.acl.adminStatus != 1:
2019-01-08 22:38:33 +05:00
return ACLManager.loadErrorJson('listContainerStatus', 0)
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
return HttpResponse(json_data)
2019-01-07 13:11:12 +00:00
def findContainersJson(self, currentACL, userID, pageNumber):
2019-01-08 12:30:13 +00:00
admin = Administrator.objects.get(pk=userID)
if admin.acl.adminStatus != 1:
return ACLManager.loadError()
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
finalPageNumber = ((pageNumber * 10)) - 10
endPageNumber = finalPageNumber + 10
containers = ACLManager.findContainersObjects(currentACL, userID)[finalPageNumber:endPageNumber]
json_data = "["
checker = 0
for items in containers:
2019-01-08 22:38:33 +05:00
dic = {'name': items.name, 'admin': items.admin.userName, 'tag': items.tag, 'image': items.image}
2019-01-07 13:11:12 +00:00
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
2019-01-08 22:38:33 +05:00
def doContainerAction(self, userID=None, data=None):
2019-01-07 13:11:12 +00:00
try:
name = data['name']
if ACLManager.checkContainerOwnership(name, userID) != 1:
2019-01-08 22:38:33 +05:00
return ACLManager.loadErrorJson('containerActionStatus', 0)
2019-01-08 12:30:13 +00:00
client = docker.from_env()
dockerAPI = docker.APIClient()
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
time.sleep(3) # Wait 3 seconds for container to finish starting/stopping/restarting
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
def getContainerStatus(self, userID=None, data=None):
2019-01-07 13:11:12 +00:00
try:
name = data['name']
if ACLManager.checkContainerOwnership(name, userID) != 1:
2019-01-08 22:38:33 +05:00
return ACLManager.loadErrorJson('containerStatus', 0)
2019-01-08 12:30:13 +00:00
client = docker.from_env()
dockerAPI = docker.APIClient()
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
return HttpResponse(json_data)
def exportContainer(self, request=None, userID=None, data=None):
2019-01-07 13:11:12 +00:00
try:
name = request.GET.get('name')
if ACLManager.checkContainerOwnership(name, userID) != 1:
2019-01-08 22:38:33 +05:00
return ACLManager.loadErrorJson('containerStatus', 0)
2019-01-08 12:30:13 +00:00
client = docker.from_env()
dockerAPI = docker.APIClient()
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
eFile = container.export() # Export with default chunk size
response = HttpResponse(eFile, content_type='application/force-download')
response['Content-Disposition'] = 'attachment; filename="' + name + '.tar"'
2019-01-07 13:11:12 +00:00
return response
except BaseException, msg:
data_ret = {'containerStatus': 0, 'error_message': str(msg)}
json_data = json.dumps(data_ret)
2019-01-08 22:38:33 +05:00
return HttpResponse(json_data)
def getContainerTop(self, userID=None, data=None):
2019-01-07 13:11:12 +00:00
try:
name = data['name']
if ACLManager.checkContainerOwnership(name, userID) != 1:
2019-01-08 22:38:33 +05:00
return ACLManager.loadErrorJson('containerTopStatus', 0)
2019-01-08 12:30:13 +00:00
client = docker.from_env()
dockerAPI = docker.APIClient()
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
try:
top = container.top()
except docker.errors.APIError as err:
data_ret = {'containerTopStatus': 0, 'error_message': str(err)}
json_data = json.dumps(data_ret)
2019-01-08 22:38:33 +05:00
return HttpResponse(json_data)
2019-01-07 13:11:12 +00:00
2019-01-08 22:38:33 +05:00
data_ret = {'containerTopStatus': 1, 'error_message': 'None', 'processes': top}
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
return HttpResponse(json_data)
def assignContainer(self, userID=None, data=None):
2019-01-07 13:11:12 +00:00
try:
# Todo: add check only for super user i.e. main admin
2019-01-08 12:30:13 +00:00
admin = Administrator.objects.get(pk=userID)
if admin.acl.adminStatus != 1:
2019-01-08 22:38:33 +05:00
return ACLManager.loadErrorJson('assignContainerStatus', 0)
2019-01-08 12:30:13 +00:00
client = docker.from_env()
dockerAPI = docker.APIClient()
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
name = data['name']
dockerOwner = data['admin']
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
admin = Administrator.objects.get(userName=dockerOwner)
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
con = Containers(admin=admin,
2019-01-08 22:38:33 +05:00
name=name,
cid=container.id)
2019-01-07 13:11:12 +00:00
con.save()
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
return HttpResponse(json_data)
def searchImage(self, userID=None, data=None):
2019-01-07 13:11:12 +00:00
try:
2019-01-08 12:30:13 +00:00
admin = Administrator.objects.get(pk=userID)
if admin.acl.adminStatus != 1:
2019-01-08 22:38:33 +05:00
return ACLManager.loadErrorJson('searchImageStatus', 0)
2019-01-08 12:30:13 +00:00
client = docker.from_env()
dockerAPI = docker.APIClient()
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
print json.dumps(matches)
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
for image in matches:
if "/" in image['name']:
image['name2'] = image['name'].split("/")[0] + ":" + image['name'].split("/")[1]
else:
image['name2'] = image['name']
2019-01-08 22:38:33 +05:00
data_ret = {'searchImageStatus': 1, 'error_message': 'None', 'matches': matches}
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
return HttpResponse(json_data)
def images(self, request=None, userID=None, data=None):
2019-01-07 13:11:12 +00:00
try:
2019-01-08 12:30:13 +00:00
admin = Administrator.objects.get(pk=userID)
if admin.acl.adminStatus != 1:
return ACLManager.loadError()
2019-01-08 22:38:33 +05:00
2019-01-08 12:30:13 +00:00
client = docker.from_env()
dockerAPI = docker.APIClient()
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
try:
imageList = client.images.list()
except docker.errors.APIError as err:
return HttpResponse(str(err))
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
images = {}
names = []
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
tags = []
for tag in image.tags:
getTag = tag.split(":")
if len(getTag) == 2:
tags.append(getTag[1])
2019-01-08 22:38:33 +05:00
print tags
2019-01-07 13:11:12 +00:00
if name in names:
images[name]['tags'].extend(tags)
else:
names.append(name)
2019-01-08 22:38:33 +05:00
images[name] = {"name": name,
"name2": name2,
"tags": tags}
2019-01-07 13:11:12 +00:00
print "======"
print images
2019-01-08 22:38:33 +05:00
return render(request, 'dockerManager/images.html', {"images": images, "test": ''})
2019-01-07 13:11:12 +00:00
except BaseException, msg:
return HttpResponse(str(msg))
2019-01-08 22:38:33 +05:00
def manageImages(self, request=None, userID=None, data=None):
2019-01-07 13:11:12 +00:00
try:
2019-01-08 12:30:13 +00:00
admin = Administrator.objects.get(pk=userID)
if admin.acl.adminStatus != 1:
return ACLManager.loadError()
2019-01-08 22:38:33 +05:00
2019-01-08 12:30:13 +00:00
client = docker.from_env()
dockerAPI = docker.APIClient()
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
imageList = client.images.list()
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
images = {}
names = []
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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)
tags = []
2019-01-08 22:38:33 +05:00
images[name] = {"name": name,
"tags": image.tags}
return render(request, 'dockerManager/manageImages.html', {"images": images})
2019-01-07 13:11:12 +00:00
except BaseException, msg:
return HttpResponse(str(msg))
2019-01-08 22:38:33 +05:00
def getImageHistory(self, userID=None, data=None):
2019-01-07 13:11:12 +00:00
try:
name = data['name']
2019-01-08 22:38:33 +05:00
2019-01-08 12:30:13 +00:00
client = docker.from_env()
dockerAPI = docker.APIClient()
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
data_ret = {'imageHistoryStatus': 1, 'error_message': 'None', 'history': image.history()}
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
def removeImage(self, userID=None, data=None):
2019-01-07 13:11:12 +00:00
try:
2019-01-08 12:30:13 +00:00
admin = Administrator.objects.get(pk=userID)
2019-01-09 14:55:10 +05:00
2019-01-08 12:30:13 +00:00
if admin.acl.adminStatus != 1:
return ACLManager.loadError()
2019-01-08 22:38:33 +05:00
2019-01-08 12:30:13 +00:00
client = docker.from_env()
dockerAPI = docker.APIClient()
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
name = data['name']
try:
if name == 0:
2019-01-08 22:38:33 +05:00
action = client.images.prune()
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
return HttpResponse(json_data)
# Internal function for recreating containers
2019-01-07 13:11:12 +00:00
def doRecreateContainer(self, userID, data, con):
try:
name = data['name']
2019-01-08 22:38:33 +05:00
unlisted = data['unlisted'] # Pass this as 1 if image is not known for container
2019-01-07 13:11:12 +00:00
image = data['image']
tag = data['tag']
env = data['env']
port = data['ports']
memory = data['memory']
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
if image == 'unknown':
return "Image name not known"
# Call container delete function
delStatus = self.submitContainerDeletion(userID, data, True)
if delStatus != 0:
return delStatus
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
print env
2019-01-08 22:38:33 +05:00
containerArgs = {'image': image + ":" + tag,
'detach': True,
'name': name,
'ports': port,
'environment': env,
'publish_all_ports': True,
'mem_limit': memory * 1048576}
2019-01-07 13:11:12 +00:00
if con.startOnReboot == 1:
containerArgs['restart_policy'] = {"Name": "always"}
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
container = client.containers.create(**containerArgs)
con.cid = container.id
con.save()
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
return 0
except BaseException, msg:
return str(msg)
2019-01-08 22:38:33 +05:00
def saveContainerSettings(self, userID=None, data=None):
try:
2019-01-07 13:11:12 +00:00
name = data['name']
if ACLManager.checkContainerOwnership(name, userID) != 1:
2019-01-08 22:38:33 +05:00
return ACLManager.loadErrorJson('saveSettingsStatus', 0)
2019-01-08 12:30:13 +00:00
client = docker.from_env()
dockerAPI = docker.APIClient()
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
memory = data['memory']
startOnReboot = data['startOnReboot']
envList = data['envList']
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
if startOnReboot == True:
startOnReboot = 1
rPolicy = {"Name": "always"}
else:
startOnReboot = 0
rPolicy = {}
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
try:
container.update(mem_limit=memory * 1048576,
2019-01-08 22:38:33 +05:00
restart_policy=rPolicy)
2019-01-07 13:11:12 +00:00
except docker.errors.APIError as err:
data_ret = {'saveSettingsStatus': 0, 'error_message': str(err)}
json_data = json.dumps(data_ret)
2019-01-08 22:38:33 +05:00
return HttpResponse(json_data)
2019-01-07 13:11:12 +00:00
con = Containers.objects.get(name=name)
con.memory = memory
con.startOnReboot = startOnReboot
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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']
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
print envDict
# Prepare data for recreate function
data = {
'name': name,
2019-01-08 22:38:33 +05:00
'unlisted': 0,
2019-01-07 13:11:12 +00:00
'image': con.image,
'tag': con.tag,
'env': envDict,
2019-01-08 22:38:33 +05:00
'ports': json.loads(con.ports),
# No filter needed now as its ports are filtered when adding to database
2019-01-07 13:11:12 +00:00
'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)
2019-01-08 22:38:33 +05:00
return HttpResponse(json_data)
2019-01-07 13:11:12 +00:00
con.env = json.dumps(envDict)
2019-01-08 22:38:33 +05:00
con.save()
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
return HttpResponse(json_data)
def recreateContainer(self, userID=None, data=None):
2019-01-07 13:11:12 +00:00
try:
name = data['name']
if ACLManager.checkContainerOwnership(name, userID) != 1:
2019-01-08 22:38:33 +05:00
return ACLManager.loadErrorJson('saveSettingsStatus', 0)
2019-01-08 12:30:13 +00:00
client = docker.from_env()
dockerAPI = docker.APIClient()
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
con = Containers.objects.get(name=name)
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
# Prepare data for recreate function
data = {
'name': name,
'unlisted': 0,
'image': con.image,
'tag': con.tag,
'env': json.loads(con.env),
2019-01-08 22:38:33 +05:00
'ports': json.loads(con.ports),
# No filter needed now as its ports are filtered when adding to database
2019-01-07 13:11:12 +00:00
'memory': con.memory
}
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
recreateStatus = self.doRecreateContainer(userID, data, con)
if recreateStatus != 0:
data_ret = {'recreateContainerStatus': 0, 'error_message': str(recreateStatus)}
json_data = json.dumps(data_ret)
2019-01-08 22:38:33 +05:00
return HttpResponse(json_data)
2019-01-07 13:11:12 +00:00
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)
2019-01-08 22:38:33 +05:00
return HttpResponse(json_data)
def getTags(self, userID=None, data=None):
2019-01-07 13:11:12 +00:00
try:
2019-01-08 22:38:33 +05:00
2019-01-08 12:30:13 +00:00
admin = Administrator.objects.get(pk=userID)
if admin.acl.adminStatus != 1:
return ACLManager.loadError()
2019-01-08 22:38:33 +05:00
2019-01-07 13:11:12 +00:00
image = data['image']
page = data['page']
if ":" in image:
image2 = image.split(":")[0] + "/" + image.split(":")[1]
else:
image2 = "library/" + image
print image
2019-01-08 22:38:33 +05:00
registryData = requests.get('https://registry.hub.docker.com/v2/repositories/' + image2 + '/tags',
{'page': page}).json()
2019-01-07 13:11:12 +00:00
tagList = []
for tag in registryData['results']:
tagList.append(tag['name'])
2019-01-08 22:38:33 +05:00
data_ret = {'getTagsStatus': 1, 'list': tagList, 'next': registryData['next'], 'error_message': None}
2019-01-07 13:11:12 +00:00
json_data = json.dumps(data_ret)
2019-01-08 22:38:33 +05:00
return HttpResponse(json_data)
2019-01-07 13:11:12 +00:00
except BaseException, msg:
data_ret = {'getTagsStatus': 0, 'error_message': str(msg)}
json_data = json.dumps(data_ret)
2019-01-08 22:38:33 +05:00
return HttpResponse(json_data)