Docker app beta

This commit is contained in:
Chirag Aggarwal
2019-01-07 13:11:12 +00:00
parent 84191cc379
commit 9a52efcfd2
36 changed files with 4348 additions and 35 deletions

View File

6
dockerManager/admin.py Normal file
View File

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

8
dockerManager/apps.py Normal file
View File

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

View File

@@ -0,0 +1,47 @@
from django.shortcuts import render,redirect
from loginSystem.models import Administrator
import os
import docker
import json
from django.http import HttpResponse
from loginSystem.views import loadLoginPage
def preDockerRun(function):
def wrap(request, *args, **kwargs):
try:
val = request.session['userID']
except KeyError:
return redirect(loadLoginPage)
admin = Administrator.objects.get(pk=val)
if request.method == "POST":
isPost = True
else:
isPost = False
# check if docker is installed
dockerInstallPath = '/usr/bin/docker'
if not os.path.exists(dockerInstallPath):
if isPost:
data_ret = {'status': 0, 'error_message': 'Docker not installed'}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
else:
return render(request, 'dockerManager/install.html', {'status':admin.type, 'conErr':0})
# Check if docker is running and we are able to connect
try:
client = docker.from_env()
client.ping()
except:
if isPost:
data_ret = {'status': 0, 'error_message': 'Docker daemon not running or not responsive'}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
else:
return render(request, 'dockerManager/install.html', {'status':admin.type, 'conErr':1})
return function(request, *args, **kwargs)
return wrap

17
dockerManager/models.py Normal file
View File

@@ -0,0 +1,17 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
from loginSystem.models import Administrator
# Create your models here.
class Containers(models.Model):
name = models.CharField(max_length=50,unique=True)
cid = models.CharField(max_length=64, default='')
admin = models.ForeignKey(Administrator)
image = models.CharField(max_length=50, default='unknown')
tag = models.CharField(max_length=50, default='unknown')
memory = models.IntegerField(default=0)
ports = models.TextField(default="{}")
env = models.TextField(default="{}")
startOnReboot = models.IntegerField(default=0)

View File

@@ -0,0 +1,12 @@
from signals import *
from plogical.pluginManagerGlobal import pluginManagerGlobal
class pluginManager:
@staticmethod
def preDockerInstallation(request):
return pluginManagerGlobal.globalPlug(request, preDockerInstallation)
@staticmethod
def postDockerInstallation(request, response):
return pluginManagerGlobal.globalPlug(request, postDockerInstallation, response)

10
dockerManager/signals.py Normal file
View File

@@ -0,0 +1,10 @@
# The world is a prison for the believer.
## https://www.youtube.com/watch?v=DWfNYztUM1U
from django.dispatch import Signal
## This event is fired before CyberPanel core start installation of Docker
preDockerInstallation = Signal(providing_args=["request"])
## This event is fired after CyberPanel core finished intallation of Docker.
postDockerInstallation = Signal(providing_args=["request", "response"])

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,64 @@
{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% block title %}{% trans "Docker Manage Images - CyberPanel" %}{% endblock %}
{% block content %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div class="container" ng-controller="manageImages">
<div id="page-title">
<h2>{% trans "Create new container" %}
<a href="{% url 'manageImages' %}" class="btn btn-info pull-right" title="{% trans 'Search new images and manage existing ones' %}">Manage Images</a>
</h2>
</div>
<div class="panel">
<div class="panel-body">
<h3 class="title-hero">
{% trans "Installed Images" %} <img id="imageLoading" src="/static/images/loading.gif" style="display: none;">
{{ test }}
</h3><br>
<div class="example-box-wrapper">
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered" id="imageList">
<thead>
<tr>
<th>Name (Installed)</th>
<th>Tags</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% for name, image in images.items %}
<tr>
<td>{{image.name}}</td>
<td>
<select class="form-control tagList" id="{{forloop.counter}}" ng-model="imageTag['{{ image.name2 }}']">
{% for tag in image.tags%}
<option>{{tag}}</option>
{% endfor %}
</select>
</td>
<td>
<a class="btn btn-primary" ng-href="/docker/runContainer/?image={{image.name}}&tag={$ imageTag['{{ image.name2 }}'] $}">{% trans "Create" %}</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,67 @@
{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% block title %}{% trans "Docker Container Management - CyberPanel" %}{% endblock %}
{% block content %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div class="container">
<div id="page-title">
<h2>{% trans "Docker Container Management" %}</h2>
</div>
<div class="panel">
<div class="panel-body">
<h3 class="title-hero">
{% trans "Available Functions" %}
</h3>
<div class="example-box-wrapper">
<div class="row">
<div class="col-md-4">
<a href="{% url 'listContainers' %}" title="{% trans 'Manage Containers' %}" class="tile-box tile-box-shortcut btn-primary">
<div class="tile-header">
{% trans "Manage Containers" %}
</div>
<div class="tile-content-wrapper">
<i class="glyph-icon icon-dashboard"></i>
</div>
</a>
</div>
<div class="col-md-4">
<a href="{% url 'containerImage' %}" title="{% trans 'Create new container' %}" class="tile-box tile-box-shortcut btn-primary">
<div class="tile-header">
{% trans "New Container" %}
</div>
<div class="tile-content-wrapper">
<i class="glyph-icon icon-dashboard"></i>
</div>
</a>
</div>
<div class="col-md-4">
<a href="{% url 'manageImages' %}" title="{% trans 'Manage Images' %}" class="tile-box tile-box-shortcut btn-primary">
<div class="tile-header">
{% trans "Manage Images" %}
</div>
<div class="tile-content-wrapper">
<i class="glyph-icon icon-dashboard"></i>
</div>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,50 @@
{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% block title %}{% trans "Install Docker - CyberPanel" %}{% endblock %}
{% block content %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div class="container">
<div id="page-title">
<h2>{% trans "Install Docker" %}</h2>
</div>
<div ng-controller="installDocker" class="panel">
<div class="panel-body">
<h3 class="title-hero">
{% trans "Install Docker" %} <img ng-hide="installDockerStatus" src="{% static 'images/loading.gif' %}">
</h3>
<div class="example-box-wrapper">
{% if conErr == 1%}
{% if status == 1 %}
{% trans "Unable to connect to docker daemon, please try restarting docker from service page" %}
{% else %}
{% trans "You do not have sufficient permissions to access this page" %}
{% endif %}
{% else %}
<p>{% trans "Docker is currently not installed on this server. To manage containers, you must first install it." %}</p>
<br>
{% if status == 1 %}
<button class="btn btn-primary" ng-click="installDocker()">Install Docker</button>
{% else %}
{% trans "You do not have permissions to install Docker. Please contact your system administrator" %}
{% endif %}
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,177 @@
{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% block title %}{% trans "Containers List - CyberPanel" %}{% endblock %}
{% block content %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div class="container">
<div id="page-title">
<h2 id="domainNamePage">{% trans "List Containers" %}
<a class="pull-right btn btn-primary" href="{% url "containerImage" %}">Create</a>
</h2>
<p>{% trans "Manage containers on server" %}</p>
</div>
<div class="panel">
<div class="panel-body">
<h3 class="title-hero">
{% trans "Containers" %} <img id="imageLoading" src="/static/images/loading.gif" style="display: none;">
</h3>
<div ng-controller="listContainers" class="example-box-wrapper">
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered" id="datatable-example">
<thead>
<tr>
<th>Name</th>
<th>Launch</th>
<th>Owner</th>
<th>Image</th>
<th>Tag</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="web in ContainerList track by $index">
<td ng-bind="web.name"></td>
<td><a href="/docker/view/{$ web.name $}"><img width="30px" height="30" class="center-block" src="{% static 'baseTemplate/assets/image-resources/webPanel.png' %}"></a></td>
<td ng-bind="web.admin"></td>
<td ng-bind="web.image"></td>
<td ng-bind="web.tag"></td>
<td>
<button class="btn btn-primary" ng-click="delContainer(web.name)"><i class="fa fa-trash"></i></button>
<button class="btn btn-primary" ng-click="showLog(web.name)"><i class="fa fa-file"></i></button>
</td>
</tr>
</tbody>
</table>
<div id="listFail" class="alert alert-danger">
<p>{% trans "Error message:" %} {$ errorMessage $}</p>
</div>
<div class="row">
<div class="col-sm-4 col-sm-offset-8">
<nav aria-label="Page navigation">
<ul class="pagination">
{% for items in pagination %}
<li ng-click="getFurtherContainersFromDB({{ forloop.counter }})" id="webPages"><a href="">{{ forloop.counter }}</a></li>
{% endfor %}
</ul>
</nav>
</div>
</div>
{% if showUnlistedContainer %}
<h3 class="title-hero">
{% trans "Unlisted Containers" %} <i class="fa fa-question-circle" title="{% trans "Containers listed below were either not created through panel or were not saved to database properly" %}"></i>
</h3>
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered" id="datatable-example">
<thead>
<tr>
<th>Name</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for container in unlistedContainers %}
<tr>
<td>{{container.name}}</td>
<td>{{container.status}}</td>
<td>
<button class="btn btn-primary" ng-click="delContainer('{{container.name}}', true)"><i class="fa fa-trash"></i></button>
<button class="btn btn-primary" ng-click="showLog('{{container.name}}')"><i class="fa fa-file"></i></button>
<button class="btn btn-primary" ng-click="assignContainer('{{container.name}}')"><i class="fa fa-user"></i></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
<div id="logs" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">Container logs</h4>
</div>
<div class="modal-body">
<textarea name="logs" class="form-control" id="" cols="30" rows="10">{$ logs $}</textarea>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" ng-click="showLog('', true)">Refresh</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div id="assign" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">Assign Container to user</h4>
</div>
<div class="modal-body">
<form action="/" class="form-horizontal">
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Select Owner" %}</label>
<div class="col-sm-6">
<select ng-model="dockerOwner" class="form-control">
{% for user in adminNames %}
<option>{{user}}</option>
{% endfor %}
</select>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" ng-click="submitAssignContainer()">Submit</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,151 @@
{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% block title %}{% trans "Docker Manage Images - CyberPanel" %}{% endblock %}
{% block content %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div class="container" ng-controller="manageImages">
<div id="page-title">
<h2 id="domainNamePage">{% trans "Manage Images" %}
<a class="pull-right btn btn-primary" href="{% url "containerImage" %}">Create</a>
</h2>
<p>{% trans "On this page you can manage docker images." %}</p>
</div>
<div id="history" class="modal fade" role="dialog">
<div class="modal-dialog" style="width:96%">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">Image history</h4>
</div>
<div class="modal-body">
<table cellpadding="0" cellspacing="0" border="0" class="table table-responsive table-striped table-bordered" id="datatable-example">
<thead>
<tr>
<th>ID</th>
<th>CreatedBy</th>
<th>Created</th>
<th>Comment</th>
<th>Size</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="history in historyList track by $index">
<th style="word-break: break-all;" ng-bind="history.Id"></th>
<th style="word-break: break-all;" ng-bind="history.CreatedBy"></th>
<th ng-bind="history.Created"></th>
<th ng-bind="history.Comment"></th>
<th ng-bind="history.Size"></th>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="panel">
<div class="panel-body">
<h3 class="title-hero">
{% trans "Images" %}
{% trans "Images" %} <img id="imageLoading" src="/static/images/loading.gif" style="display: none;">
<button class="btn btn-warning pull-right" ng-click="rmImage(0)" title="{% trans 'Delete unused images' %}">Prune</button>
</h3><br>
<div class="row">
<div class="col-sm-2"></div>
<label class="col-sm-2 control-label">Search Image</label>
<div class="col-sm-6">
<input type="text" ng-change="searchImages()" ng-model="searchString" class="form-control">
</div>
<div class="col-sm-2"></div>
</div>
<br>
<div class="example-box-wrapper">
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered" id="searchResult">
<thead>
<tr>
<th>Name (search)</th>
<th>Tags</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="image in images track by $index">
<td>
<span ng-bind="image.name"></span>
<span ng-show="image.is_official == true"><i class="fa fa-check-circle" title="{% trans 'Official image' %}"></i></span>
<span><i class="fa fa-exclamation-circle" ng-attr-title="{$ image.description $}"></i></span>
</td>
<td>
<select ng-focus="loadTags($event)" ng-click="selectTag()" ng-model="imageTag[image.name2]" ng-options="tag for tag in tagList[image.name2]" ng-attr-id="{$ image.name2 $}" data-pageloaded='0' class="form-control ng-pristine ng-valid ng-empty ng-touched">
</select>
</td>
<td>
<a ng-click="pullImage(image.name, imageTag[image.name2])" class="btn btn-primary">{% trans "Pull" %}</a>
</td>
</tr>
</tbody>
</table>
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered" id="imageList">
<thead>
<tr>
<th>Name (Installed)</th>
<th>Tags</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% for name, image in images.items %}
<tr>
<td>{{image.name}}</td>
<td>
<select class="form-control tagList" id="{{forloop.counter}}">
{% for tag in image.tags%}
<option>{{tag}}</option>
{% endfor %}
</select>
</td>
<td>
<button class="btn btn-primary" title="History" ng-click="getHistory({{forloop.counter}})"><i class="fa fa-history"></i></button>
<button class="btn btn-primary" title="Delete" ng-click="rmImage({{forloop.counter}})"><i class="fa fa-trash"></i></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,170 @@
{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% block title %}{% trans "Run new container - CyberPanel" %}{% endblock %}
{% block content %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div class="container">
<div id="page-title">
<h2>{% trans "Run Container" %}</h2>
<p>{% trans "Modify parameters for your new container" %}</p>
</div>
<div ng-controller="runContainer" class="panel">
<div class="panel-body">
<h3 class="title-hero">
{% trans "Container Details" %} <img ng-hide="containerCreationLoading" src="{% static 'images/loading.gif' %}">
</h3>
<div class="example-box-wrapper">
<form name="dockerInstallForm" action="/" class="form-horizontal bordered-row">
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Name" %}</label>
<div class="col-sm-6" ng-init="name='{{name}}' ">
<input name="name" type="text" class="form-control" ng-model="name" required>
</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Image" %}</label>
<div class="col-sm-6" ng-init="image='{{image}}' ">
<input name="image" type="text" class="form-control" ng-model="image" required disabled="disabled">
</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Tag" %}</label>
<div class="col-sm-6" ng-init="tag='{{tag}}' ">
<input name="tag" type="text" class="form-control" ng-model="tag" required disabled="disabled">
</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Select Owner" %}</label>
<div class="col-sm-6">
<select ng-model="dockerOwner" class="form-control">
{% for items in ownerList %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Memory limit" %}</label>
<div class="col-sm-6">
<input name="memory" type="number" class="form-control" ng-model="memory" required>
</div>
<div class="current-pack ng-binding">MB</div>
</div>
{% for port, protocol in portConfig.items %}
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Port" %}</label>
<div class="col-sm-2" ng-init="iport[{{port}}]={{ port }} ">
<input name="iport[{{port}}]" type="text" class="form-control" ng-model="iport[{{port}}]" required disabled="disabled">
</div>
<div class="col-sm-1" ng-init="portType['{{port}}']='{{ protocol }}'" >
<input name="portType['{{port}}']" type="text" class="form-control" ng-model="portType['{{port}}']" required disabled="disabled">
</div>
<div class="col-sm-1 current-pack text-center">to</div>
<div class="col-sm-2">
<input name="eport['{{port}}']" type="number" class="form-control" ng-model="eport['{{port}}']" required>
</div>
</div>
{% endfor %}
<span ng-init="envList = {}"></span>
{% for env, value in envList.items %}
<span ng-init="envList[{{ forloop.counter0 }}] = {'name':'{{env}}' , 'value':'{{value}}'} "></span>
{% endfor %}
<hr>
<div ng-repeat="env in envList track by $index">
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">
<div ng-show="$first">
{% trans "ENV" %}
</div>
</label>
<div class="col-sm-2">
<input name="$index" type="text" class="form-control" ng-model="envList[$index].name" required>
</div>
<div class="col-sm-4">
<input name="$index" type="text" class="form-control" ng-model="envList[$index].value" required>
</div>
</div>
</div>
<div class="col-md-offset-3">
<button type="button" class="btn btn-info" ng-click="addEnvField()">Add more</button>
</div><br>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<button type="button" ng-click="createContainer()" class="btn btn-primary btn-lg btn-block">{% trans "Create Container" %}</button>
</div>
</div>
<div ng-hide="installationProgress" class="form-group">
<label class="col-sm-2 control-label"></label>
<div class="col-sm-7">
<div class="alert alert-success text-center">
<h2>{$ currentStatus $}</h2>
</div>
<div ng-hide="errorMessageBox" class="alert alert-danger">
<p>{% trans "Error message:" %} {$ errorMessage $}</p>
</div>
<div ng-hide="success" class="alert alert-success">
<p>{% trans "Container succesfully created." %}</p>
</div>
<div ng-hide="couldNotConnect" class="alert alert-danger">
<p>{% trans "Could not connect to server. Please refresh this page." %}</p>
</div>
</div>
</div>
<div ng-hide="installationProgress" class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<button type="button" ng-disabled="goBackDisable" ng-click="goBack()" class="btn btn-primary btn-lg btn-block">{% trans "Go Back" %}</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,303 @@
{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% block title %}{% trans "Container Home - CyberPanel" %}{% endblock %}
{% block content %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div class="container" ng-controller="viewContainer">
<div id="page-title" ng-init="cName='{{name}}'">
<h2 id="domainNamePage">{% trans "Manage Container" %}</h2>
<p>{% trans "Currently managing: " %} {{ name }}</p>
</div>
<div class="example-box-wrapper">
<div class="content-box">
<h3 class="content-box-header bg-blue">
{% trans "Container Information" %}
<img id="infoLoading" src="/static/images/loading.gif" style="display: none;">
</h3>
<div class="content-box-wrapper">
<div class="row">
<div class="col-md-6">
<div class="panel">
<div class="panel-body">
<div class="example-box-wrapper">
<h3 class="title-hero">
{% trans "Memory Usage" %}
</h3>
<div class="progressbar" data-value="{{ memoryUsage }}">
<div class="progressbar-value bg-primary">
<div class="progress-overlay"></div>
<div class="progress-label">{{ memoryUsage | floatformat:"2" }}%</div>
</div>
</div>
<h3 class="title-hero">
{% trans "CPU Usage" %}
</h3>
<div class="progressbar" data-value="{{ cpuUsage }}">
<div class="progressbar-value bg-primary">
<div class="progress-overlay"></div>
<div class="progress-label">{{ cpuUsage }}%</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="panel">
<div class="panel-body">
<div class="example-box-wrapper">
{% trans "Container ID" %}: {{cid}}
<br>
{% trans "Image" %}: {{image}}
<span ng-show="'{{image}}' == 'unknown:unknown'" title="Actions involving container recreation cannot be executed">
<i class="fa fa-warning"></i>
</span>
<br>
{% if ports %}
{% trans "Ports" %}: <br>
{% for iport, eport in ports.items %}
{{iport}} {% trans "to" %} {{eport}}<br>
{% endfor %}
{% endif %}
</div>
<button class="btn btn-warning" data-toggle="modal" data-target="#settings"><i class="fa fa-gear"></i> Settings</button>
<button class="btn btn-warning" ng-click="recreate()"><i class="fa fa-refresh"></i> Recreate</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="example-box-wrapper">
<div class="content-box">
<h3 class="content-box-header bg-blue">
{% trans "Actions" %}
</h3>
<div class="content-box-wrapper">
<div class="row">
<div class="col-md-6">
<div class="panel">
<div class="panel-body">
<div class="example-box-wrapper">
<h3 class="title-hero" ng-init="status='{{status}}'">Main Actions
<img id="actionLoading" src="/static/images/loading.gif" style="display: none;width: 20px;">
</h3>
<b>Status:</b> <span ng-bind="status"></span>
<span ng-click='refreshStatus()' style="cursor:pointer;" class="pull-right" title="Refresh status"><i class="fa fa-refresh"></i></span>
<hr>
<button ng-disabled="status=='running'" class="btn btn-primary" ng-click="cAction('start')"><i class="fa fa-play"></i> Start</button>
<button ng-disabled="status!='running'" class="btn btn-primary" ng-click="cAction('restart')"><i class="fa fa-refresh"></i> Restart</button>
<button ng-disabled="status!='running'" class="btn btn-primary" ng-click="cAction('stop')"><i class="fa fa-stop"></i> Stop</button>
<button class="btn btn-block btn-primary" ng-click="cRemove()">Remove</button>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="panel">
<div class="panel-body">
<div class="example-box-wrapper">
<h3 class="title-hero" ng-init="rPolicy='{{restartPolicy}}'">Other Actions</h3>
<b>Restart on system reboot:</b> <span ng-bind="rPolicy"></span><hr>
<a href="/docker/exportContainer/?name={{name}}" class="btn btn-block btn-primary">Export file</a>
<button class="btn btn-block btn-primary" ng-disabled="loadingTop" ng-click="showTop()">View Process</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="example-box-wrapper">
<div class="content-box">
<h3 class="content-box-header bg-blue" ng-init="loadLogs('{{name}}')">
{% trans "Logs" %}
<span style="cursor:pointer;" class="pull-right" ng-click="loadLogs('{{name}}')"><i class="fa fa-refresh"></i></span>
</h3>
<div class="content-box-wrapper">
<div class="row">
<textarea name="logs" class="form-control" id="" cols="30" rows="10">{$ logs $}</textarea><br>
</div>
</div>
</div>
</div>
<div id="settings" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">Container Settings
<img id="containerSettingLoading" src="/static/images/loading.gif" style="display: none;">
</h4>
</div>
<div class="modal-body">
<form name="containerSettingsForm" action="/" class="form-horizontal">
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Memory limit" %}</label>
<div class="col-sm-6" ng-init="memory={{memoryLimit}}">
<input name="memory" type="number" class="form-control" ng-model="memory" required>
</div>
<div class="current-pack ng-binding">MB</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">Start on reboot</label>
<div class="col-sm-9">
<div class="checkbox" ng-init="startOnReboot={{startOnReboot}}">
<label>
<input ng-model="startOnReboot" type="checkbox" value="" class="ng-pristine ng-untouched ng-valid ng-empty">
</label>
</div>
</div>
</div>
<hr>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Confirmation" %}</label>
<div class="col-sm-9">
<div class="checkbox">
<label>
<input ng-model="envConfirmation" type="checkbox">
Editing ENV will recreate container <i class="fa fa-warning" title="If you tick this checkbox, your container will be recreated with saved information. Data saved inside container will be deleted (Not avaialble for container created outside of cyberpanel)"></i>
</label>
</div>
</div>
</div>
<span ng-init="envList = {}"></span>
{% for env, value in envList.items %}
<span ng-init="envList[{{ forloop.counter0 }}] = {'name':'{{env}}' , 'value':'{{value}}'} "></span>
{% endfor %}
<div ng-repeat="env in envList track by $index">
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">
<div ng-show="$first">
{% trans "ENV" %}
</div>
</label>
<div class="col-sm-2">
<input name="$index" type="text" class="form-control" ng-model="envList[$index].name" required>
</div>
<div class="col-sm-4">
<input name="$index" type="text" class="form-control" ng-model="envList[$index].value" required>
</div>
</div>
</div>
<div class="col-md-offset-3">
<button type="button" class="btn btn-info" ng-click="addEnvField()">Add more</button>
</div><br>
</form>
</div>
<div class="modal-footer">
<button type="button" ng-disabled="savingSettings" class="btn btn-primary" ng-click="saveSettings()">Save</button>
<button type="button" ng-disabled="savingSettings" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div id="processes" class="modal fade" role="dialog">
<div class="modal-dialog" style="width: 96%;">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">Container Processes</h4>
</div>
<div class="modal-body">
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered" id="datatable-example">
<thead>
<tr>
<th ng-repeat="item in topHead track by $index">{$ item $}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="process in topProcesses track by $index">
<th ng-repeat="item in process track by $index">{$ item $}</th>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" ng-disabled="savingSettings" class="btn btn-primary" ng-click="showTop()">Refresh</button>
<button type="button" ng-disabled="savingSettings" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

6
dockerManager/tests.py Normal file
View File

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

29
dockerManager/urls.py Normal file
View File

@@ -0,0 +1,29 @@
from django.conf.urls import url
import views
urlpatterns = [
url(r'^$', views.loadDockerHome, name='dockerHome'),
# url(r'^images', views.loadImages, name='loadImages'),
url(r'^getTags', views.getTags, name='getTags'),
url(r'^runContainer', views.runContainer, name='runContainer'),
url(r'^submitContainerCreation', views.submitContainerCreation, name='submitContainerCreation'),
url(r'^listContainers', views.listContainers, name='listContainers'),
url(r'^getContainerList', views.getContainerList, name='getContainerList'),
url(r'^getContainerLogs', views.getContainerLogs, name='getContainerLogs'),
url(r'^installImage', views.installImage, name='installImage'),
url(r'^delContainer', views.delContainer, name='delContainer'),
url(r'^doContainerAction', views.doContainerAction, name='doContainerAction'),
url(r'^getContainerStatus', views.getContainerStatus, name='getContainerStatus'),
url(r'^exportContainer', views.exportContainer, name='exportContainer'),
url(r'^saveContainerSettings', views.saveContainerSettings, name='saveContainerSettings'),
url(r'^getContainerTop', views.getContainerTop, name='getContainerTop'),
url(r'^assignContainer', views.assignContainer, name='assignContainer'),
url(r'^searchImage', views.searchImage, name='searchImage'),
url(r'^manageImages', views.manageImages, name='manageImages'),
url(r'^getImageHistory', views.getImageHistory, name='getImageHistory'),
url(r'^removeImage', views.removeImage, name='removeImage'),
url(r'^recreateContainer', views.recreateContainer, name='recreateContainer'),
url(r'^installDocker', views.installDocker, name='installDocker'),
url(r'^images', views.images, name='containerImage'),
url(r'^view/(?P<name>(.*))$', views.viewContainer, name='viewContainer'),
]

362
dockerManager/views.py Normal file
View File

@@ -0,0 +1,362 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render,redirect
from loginSystem.models import Administrator
from loginSystem.views import loadLoginPage
from django.http import HttpResponse
from plogical.container import ContainerManager
from dockerManager.pluginManager import pluginManager
from decorators import preDockerRun
from plogical.acl import ACLManager
import json
import requests
import docker
# Use default socket to connect
client = docker.from_env()
# Create your views here.
# This function checks if user has admin permissions
def dockerPermission(request, userID, context):
currentACL = ACLManager.loadedACL(userID)
if currentACL['admin'] != 1:
if request.method == "POST":
return ACLManager.loadErrorJson()
else:
return ACLManager.loadError()
else:
return None
@preDockerRun
def loadDockerHome(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
admin = Administrator.objects.get(pk=userID)
return render(request,'dockerManager/index.html',{"type":admin.type})
except KeyError:
return redirect(loadLoginPage)
def installDocker(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
result = pluginManager.preDockerInstallation(request) # Later change to preInstallInstallation
if result != 200:
return result
cm = ContainerManager()
coreResult = cm.submitInstallDocker(userID, json.loads(request.body))
result = pluginManager.postDockerInstallation(request, coreResult)
if result != 200:
return result
return coreResult
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def installImage(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
cm = ContainerManager()
coreResult = cm.submitInstallImage(userID, json.loads(request.body))
return coreResult
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def viewContainer(request, name):
try:
if not request.GET._mutable:
request.GET._mutable = True
request.GET['name'] = name
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
cm = ContainerManager(name)
coreResult = cm.loadContainerHome(request, userID)
return coreResult
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def getTags(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
cm = ContainerManager()
coreResult = cm.getTags(userID, json.loads(request.body))
return coreResult
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def delContainer(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
cm = ContainerManager()
coreResult = cm.submitContainerDeletion(userID, json.loads(request.body))
return coreResult
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def recreateContainer(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
cm = ContainerManager()
coreResult = cm.recreateContainer(userID, json.loads(request.body))
return coreResult
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def runContainer(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
cm = ContainerManager()
return cm.createContainer(request, userID)
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def listContainers(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
cm = ContainerManager()
return cm.listContainers(request, userID)
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def getContainerLogs(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
cm = ContainerManager()
coreResult = cm.getContainerLogs(userID, json.loads(request.body))
return coreResult
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def submitContainerCreation(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
cm = ContainerManager()
coreResult = cm.submitContainerCreation(userID, json.loads(request.body))
return coreResult
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def getContainerList(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
cm = ContainerManager()
return cm.getContainerList(userID, json.loads(request.body))
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def doContainerAction(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
cm = ContainerManager()
coreResult = cm.doContainerAction(userID, json.loads(request.body))
return coreResult
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def getContainerStatus(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
cm = ContainerManager()
coreResult = cm.getContainerStatus(userID, json.loads(request.body))
return coreResult
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def exportContainer(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
cm = ContainerManager()
coreResult = cm.exportContainer(request, userID)
return coreResult
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def saveContainerSettings(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
cm = ContainerManager()
coreResult = cm.saveContainerSettings(userID, json.loads(request.body))
return coreResult
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def getContainerTop(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
cm = ContainerManager()
coreResult = cm.getContainerTop(userID, json.loads(request.body))
return coreResult
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def assignContainer(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
cm = ContainerManager()
coreResult = cm.assignContainer(userID, json.loads(request.body))
return coreResult
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def searchImage(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
cm = ContainerManager()
coreResult = cm.searchImage(userID, json.loads(request.body))
return coreResult
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def images(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'images')
if perm: return perm
cm = ContainerManager()
coreResult = cm.images(request, userID)
return coreResult
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def manageImages(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
cm = ContainerManager()
coreResult = cm.manageImages(request, userID)
return coreResult
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def getImageHistory(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
cm = ContainerManager()
coreResult = cm.getImageHistory(userID, json.loads(request.body))
return coreResult
except KeyError:
return redirect(loadLoginPage)
@preDockerRun
def removeImage(request):
try:
userID = request.session['userID']
perm = dockerPermission(request, userID, 'loadDockerHome')
if perm: return perm
cm = ContainerManager()
coreResult = cm.removeImage(userID, json.loads(request.body))
return coreResult
except KeyError:
return redirect(loadLoginPage)