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

@@ -24,7 +24,7 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_KEY = 'xr%j*p!*$0d%(-(e%@-*hyoz4$f%y77coq0u)6pwmjg4)q&19f' SECRET_KEY = 'xr%j*p!*$0d%(-(e%@-*hyoz4$f%y77coq0u)6pwmjg4)q&19f'
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False DEBUG = True
ALLOWED_HOSTS = ['*'] ALLOWED_HOSTS = ['*']
@@ -62,9 +62,7 @@ INSTALLED_APPS = [
'pluginHolder', 'pluginHolder',
'emailPremium', 'emailPremium',
'emailMarketing', 'emailMarketing',
'cloudAPI', 'dockerManager'
'highAvailability',
's3Backups'
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@@ -109,15 +107,15 @@ DATABASES = {
'ENGINE': 'django.db.backends.mysql', 'ENGINE': 'django.db.backends.mysql',
'NAME': 'cyberpanel', 'NAME': 'cyberpanel',
'USER': 'cyberpanel', 'USER': 'cyberpanel',
'PASSWORD': 'Bz9gF7Hr7X4RtD', 'PASSWORD': 'a9AwLb7zY7ZwCd',
'HOST': '127.0.0.1', 'HOST': 'localhost',
'PORT':'3307' 'PORT': '',
}, },
'rootdb': { 'rootdb': {
'ENGINE': 'django.db.backends.mysql', 'ENGINE': 'django.db.backends.mysql',
'NAME': 'mysql', 'NAME': 'mysql',
'USER': 'root', 'USER': 'root',
'PASSWORD': 'sXm5VlRaAsXkDd', 'PASSWORD': '3bL8X7wGo0kT3b',
'HOST': 'localhost', 'HOST': 'localhost',
'PORT': '', 'PORT': '',
}, },

View File

@@ -21,6 +21,7 @@ urlpatterns = [
url(r'^', include('loginSystem.urls')), url(r'^', include('loginSystem.urls')),
url(r'^packages/',include('packages.urls')), url(r'^packages/',include('packages.urls')),
url(r'^websites/',include('websiteFunctions.urls')), url(r'^websites/',include('websiteFunctions.urls')),
url(r'^docker/',include('dockerManager.urls')),
url(r'^tuning/',include('tuning.urls')), url(r'^tuning/',include('tuning.urls')),
url(r'^ftp/',include('ftp.urls')), url(r'^ftp/',include('ftp.urls')),
url(r'^serverstatus/',include('serverStatus.urls')), url(r'^serverstatus/',include('serverStatus.urls')),

View File

@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2019-01-07 12:43
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='DBUsers',
fields=[
('host', models.CharField(db_column='Host', max_length=60, primary_key=True, serialize=False)),
('user', models.CharField(db_column='User', max_length=16)),
('password', models.CharField(db_column='Password', max_length=41)),
('select_priv', models.CharField(db_column='Select_priv', max_length=1)),
('insert_priv', models.CharField(db_column='Insert_priv', max_length=1)),
('update_priv', models.CharField(db_column='Update_priv', max_length=1)),
('delete_priv', models.CharField(db_column='Delete_priv', max_length=1)),
('create_priv', models.CharField(db_column='Create_priv', max_length=1)),
('drop_priv', models.CharField(db_column='Drop_priv', max_length=1)),
('reload_priv', models.CharField(db_column='Reload_priv', max_length=1)),
('shutdown_priv', models.CharField(db_column='Shutdown_priv', max_length=1)),
('process_priv', models.CharField(db_column='Process_priv', max_length=1)),
('file_priv', models.CharField(db_column='File_priv', max_length=1)),
('grant_priv', models.CharField(db_column='Grant_priv', max_length=1)),
('references_priv', models.CharField(db_column='References_priv', max_length=1)),
('index_priv', models.CharField(db_column='Index_priv', max_length=1)),
('alter_priv', models.CharField(db_column='Alter_priv', max_length=1)),
('show_db_priv', models.CharField(db_column='Show_db_priv', max_length=1)),
('super_priv', models.CharField(db_column='Super_priv', max_length=1)),
('create_tmp_table_priv', models.CharField(db_column='Create_tmp_table_priv', max_length=1)),
('lock_tables_priv', models.CharField(db_column='Lock_tables_priv', max_length=1)),
('execute_priv', models.CharField(db_column='Execute_priv', max_length=1)),
('repl_slave_priv', models.CharField(db_column='Repl_slave_priv', max_length=1)),
('repl_client_priv', models.CharField(db_column='Repl_client_priv', max_length=1)),
('create_view_priv', models.CharField(db_column='Create_view_priv', max_length=1)),
('show_view_priv', models.CharField(db_column='Show_view_priv', max_length=1)),
('create_routine_priv', models.CharField(db_column='Create_routine_priv', max_length=1)),
('alter_routine_priv', models.CharField(db_column='Alter_routine_priv', max_length=1)),
('create_user_priv', models.CharField(db_column='Create_user_priv', max_length=1)),
('event_priv', models.CharField(db_column='Event_priv', max_length=1)),
('trigger_priv', models.CharField(db_column='Trigger_priv', max_length=1)),
('create_tablespace_priv', models.CharField(db_column='Create_tablespace_priv', max_length=1)),
('ssl_type', models.CharField(max_length=9)),
('ssl_cipher', models.TextField()),
('x509_issuer', models.TextField()),
('x509_subject', models.TextField()),
('max_questions', models.IntegerField()),
('max_updates', models.IntegerField()),
('max_connections', models.IntegerField()),
('max_user_connections', models.IntegerField()),
('plugin', models.CharField(max_length=64)),
('authentication_string', models.TextField()),
],
options={
'db_table': 'user',
},
),
migrations.AlterUniqueTogether(
name='dbusers',
unique_together=set([('host', 'user')]),
),
]

View File

@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2019-01-07 12:43
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='version',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('currentVersion', models.CharField(max_length=50)),
('build', models.IntegerField()),
],
),
]

View File

@@ -666,6 +666,7 @@
<script src="{% static 'managePHP/managePHP.js' %}"></script> <script src="{% static 'managePHP/managePHP.js' %}"></script>
<script src="{% static 'baseTemplate/bootstrap-toggle.min.js' %}"></script> <script src="{% static 'baseTemplate/bootstrap-toggle.min.js' %}"></script>
<script src="{% static 'firewall/firewall.js' %}"></script> <script src="{% static 'firewall/firewall.js' %}"></script>
<script src="{% static 'dockerManager/dockerManager.js' %}"></script>
<script src="{% static 'manageSSL/manageSSL.js' %}"></script> <script src="{% static 'manageSSL/manageSSL.js' %}"></script>
<script src="{% static 'manageServices/manageServices.js' %}"></script> <script src="{% static 'manageServices/manageServices.js' %}"></script>
</div> </div>

View File

@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2019-01-07 12:43
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('websiteFunctions', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Databases',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('dbName', models.CharField(max_length=50, unique=True)),
('dbUser', models.CharField(max_length=50, unique=True)),
('website', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='websiteFunctions.Websites')),
],
),
]

View File

@@ -0,0 +1,125 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2019-01-07 12:43
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('loginSystem', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Comments',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('domain_id', models.IntegerField()),
('name', models.CharField(max_length=255)),
('type', models.CharField(max_length=10)),
('modified_at', models.IntegerField()),
('account', models.CharField(max_length=40)),
('comment', models.CharField(max_length=64000)),
],
options={
'db_table': 'comments',
},
),
migrations.CreateModel(
name='Cryptokeys',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('domain_id', models.IntegerField()),
('flags', models.IntegerField()),
('active', models.IntegerField(blank=True, null=True)),
('content', models.TextField(blank=True, null=True)),
],
options={
'db_table': 'cryptokeys',
},
),
migrations.CreateModel(
name='Domainmetadata',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('domain_id', models.IntegerField()),
('kind', models.CharField(blank=True, max_length=32, null=True)),
('content', models.TextField(blank=True, null=True)),
],
options={
'db_table': 'domainmetadata',
},
),
migrations.CreateModel(
name='Domains',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, unique=True)),
('master', models.CharField(blank=True, max_length=128, null=True)),
('last_check', models.IntegerField(blank=True, null=True)),
('type', models.CharField(max_length=6)),
('notified_serial', models.IntegerField(blank=True, null=True)),
('account', models.CharField(blank=True, max_length=40, null=True)),
('admin', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='loginSystem.Administrator')),
],
options={
'db_table': 'domains',
},
),
migrations.CreateModel(
name='Records',
fields=[
('id', models.BigAutoField(primary_key=True, serialize=False)),
('domain_id', models.IntegerField(blank=True, null=True)),
('name', models.CharField(blank=True, max_length=255, null=True)),
('type', models.CharField(blank=True, max_length=10, null=True)),
('content', models.CharField(blank=True, max_length=64000, null=True)),
('ttl', models.IntegerField(blank=True, null=True)),
('prio', models.IntegerField(blank=True, null=True)),
('change_date', models.IntegerField(blank=True, null=True)),
('disabled', models.IntegerField(blank=True, null=True)),
('ordername', models.CharField(blank=True, max_length=255, null=True)),
('auth', models.IntegerField(blank=True, null=True)),
('domainOwner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='dns.Domains')),
],
options={
'db_table': 'records',
},
),
migrations.CreateModel(
name='Supermasters',
fields=[
('ip', models.CharField(max_length=64, primary_key=True, serialize=False)),
('nameserver', models.CharField(max_length=255)),
('account', models.CharField(max_length=40)),
],
options={
'db_table': 'supermasters',
},
),
migrations.CreateModel(
name='Tsigkeys',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(blank=True, max_length=255, null=True)),
('algorithm', models.CharField(blank=True, max_length=50, null=True)),
('secret', models.CharField(blank=True, max_length=255, null=True)),
],
options={
'db_table': 'tsigkeys',
},
),
migrations.AlterUniqueTogether(
name='tsigkeys',
unique_together=set([('name', 'algorithm')]),
),
migrations.AlterUniqueTogether(
name='supermasters',
unique_together=set([('ip', 'nameserver')]),
),
]

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)

View File

@@ -0,0 +1,87 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2019-01-07 12:43
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('websiteFunctions', '0001_initial'),
('loginSystem', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='EmailJobs',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('date', models.CharField(max_length=200)),
('host', models.CharField(max_length=1000)),
('totalEmails', models.IntegerField()),
('sent', models.IntegerField()),
('failed', models.IntegerField()),
],
),
migrations.CreateModel(
name='EmailLists',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('listName', models.CharField(max_length=50, unique=True)),
('dateCreated', models.CharField(max_length=200)),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='websiteFunctions.Websites')),
],
),
migrations.CreateModel(
name='EmailMarketing',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('userName', models.CharField(max_length=50, unique=True)),
],
),
migrations.CreateModel(
name='EmailsInList',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('email', models.CharField(max_length=50)),
('firstName', models.CharField(default='', max_length=20)),
('lastName', models.CharField(default='', max_length=20)),
('verificationStatus', models.CharField(max_length=100)),
('dateCreated', models.CharField(max_length=200)),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='emailMarketing.EmailLists')),
],
),
migrations.CreateModel(
name='EmailTemplate',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100, unique=True)),
('subject', models.CharField(max_length=1000)),
('fromName', models.CharField(max_length=100)),
('fromEmail', models.CharField(max_length=150)),
('replyTo', models.CharField(max_length=150)),
('emailMessage', models.CharField(max_length=3000000)),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='loginSystem.Administrator')),
],
),
migrations.CreateModel(
name='SMTPHosts',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('host', models.CharField(max_length=150, unique=True)),
('port', models.CharField(max_length=10)),
('userName', models.CharField(max_length=50)),
('password', models.CharField(max_length=50)),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='loginSystem.Administrator')),
],
),
migrations.AddField(
model_name='emailjobs',
name='owner',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='emailMarketing.EmailTemplate'),
),
]

View File

@@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2019-01-07 12:43
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('mailServer', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='DomainLimits',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('limitStatus', models.IntegerField(default=0)),
('monthlyLimit', models.IntegerField(default=10000)),
('monthlyUsed', models.IntegerField(default=0)),
('domain', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mailServer.Domains')),
],
),
migrations.CreateModel(
name='EmailLimits',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('limitStatus', models.IntegerField(default=0)),
('monthlyLimits', models.IntegerField(default=2000)),
('monthlyUsed', models.IntegerField(default=0)),
('hourlyLimit', models.IntegerField(default=50)),
('hourlyUsed', models.IntegerField(default=0)),
('emailLogs', models.IntegerField(default=0)),
('email', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mailServer.EUsers')),
],
),
migrations.CreateModel(
name='EmailLogs',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('destination', models.CharField(max_length=200)),
('timeStamp', models.CharField(max_length=200)),
('email', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mailServer.EUsers')),
],
),
]

View File

@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2019-01-07 12:43
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='FirewallRules',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=32, unique=True)),
('proto', models.CharField(max_length=10)),
('port', models.CharField(max_length=25)),
('ipAddress', models.CharField(default=b'0.0.0.0/0', max_length=30)),
],
),
]

View File

@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2019-01-07 12:43
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('websiteFunctions', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Users',
fields=[
('id', models.AutoField(db_column=b'ID', primary_key=True, serialize=False)),
('user', models.CharField(db_column=b'User', max_length=32, unique=True)),
('password', models.CharField(db_column=b'Password', max_length=64)),
('uid', models.IntegerField(db_column=b'Uid')),
('gid', models.IntegerField(db_column=b'Gid')),
('dir', models.CharField(db_column=b'Dir', max_length=255)),
('quotasize', models.IntegerField(db_column=b'QuotaSize')),
('status', models.CharField(db_column=b'Status', max_length=1)),
('ulbandwidth', models.IntegerField(db_column=b'ULBandwidth')),
('dlbandwidth', models.IntegerField(db_column=b'DLBandwidth')),
('date', models.DateField(db_column=b'Date')),
('lastmodif', models.CharField(db_column=b'LastModif', max_length=255)),
('domain', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='websiteFunctions.Websites')),
],
options={
'db_table': 'users',
},
),
]

View File

@@ -0,0 +1,76 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2019-01-07 12:43
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='ACL',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50, unique=True)),
('adminStatus', models.IntegerField(default=0)),
('versionManagement', models.IntegerField(default=0)),
('createNewUser', models.IntegerField(default=0)),
('deleteUser', models.IntegerField(default=0)),
('resellerCenter', models.IntegerField(default=0)),
('changeUserACL', models.IntegerField(default=0)),
('createWebsite', models.IntegerField(default=0)),
('modifyWebsite', models.IntegerField(default=0)),
('suspendWebsite', models.IntegerField(default=0)),
('deleteWebsite', models.IntegerField(default=0)),
('createPackage', models.IntegerField(default=0)),
('deletePackage', models.IntegerField(default=0)),
('modifyPackage', models.IntegerField(default=0)),
('createDatabase', models.IntegerField(default=1)),
('deleteDatabase', models.IntegerField(default=1)),
('listDatabases', models.IntegerField(default=1)),
('createNameServer', models.IntegerField(default=0)),
('createDNSZone', models.IntegerField(default=1)),
('deleteZone', models.IntegerField(default=1)),
('addDeleteRecords', models.IntegerField(default=1)),
('createEmail', models.IntegerField(default=1)),
('deleteEmail', models.IntegerField(default=1)),
('emailForwarding', models.IntegerField(default=1)),
('changeEmailPassword', models.IntegerField(default=1)),
('dkimManager', models.IntegerField(default=1)),
('createFTPAccount', models.IntegerField(default=1)),
('deleteFTPAccount', models.IntegerField(default=1)),
('listFTPAccounts', models.IntegerField(default=1)),
('createBackup', models.IntegerField(default=1)),
('restoreBackup', models.IntegerField(default=0)),
('addDeleteDestinations', models.IntegerField(default=0)),
('scheDuleBackups', models.IntegerField(default=0)),
('remoteBackups', models.IntegerField(default=0)),
('manageSSL', models.IntegerField(default=1)),
('hostnameSSL', models.IntegerField(default=0)),
('mailServerSSL', models.IntegerField(default=0)),
],
),
migrations.CreateModel(
name='Administrator',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('userName', models.CharField(max_length=50, unique=True)),
('password', models.CharField(max_length=200)),
('firstName', models.CharField(default='None', max_length=20)),
('lastName', models.CharField(default='None', max_length=20)),
('email', models.CharField(max_length=50)),
('type', models.IntegerField()),
('owner', models.IntegerField(default=1)),
('token', models.CharField(default='None', max_length=500)),
('initWebsitesLimit', models.IntegerField(default=0)),
('acl', models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='loginSystem.ACL')),
],
),
]

View File

@@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2019-01-07 12:43
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('websiteFunctions', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Domains',
fields=[
('domain', models.CharField(max_length=50, primary_key=True, serialize=False)),
('domainOwner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='websiteFunctions.Websites')),
],
options={
'db_table': 'e_domains',
},
),
migrations.CreateModel(
name='EUsers',
fields=[
('email', models.CharField(max_length=80, primary_key=True, serialize=False)),
('password', models.CharField(max_length=20)),
('emailOwner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mailServer.Domains')),
],
options={
'db_table': 'e_users',
},
),
migrations.CreateModel(
name='Forwardings',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('source', models.CharField(max_length=80)),
('destination', models.TextField()),
],
options={
'db_table': 'e_forwardings',
},
),
migrations.CreateModel(
name='Transport',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('domain', models.CharField(max_length=128, unique=True)),
('transport', models.CharField(max_length=128)),
],
options={
'db_table': 'e_transport',
},
),
]

View File

@@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2019-01-07 12:43
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='installedPackages',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('extensionName', models.CharField(max_length=50)),
('description', models.CharField(max_length=255)),
('status', models.IntegerField()),
],
),
migrations.CreateModel(
name='PHP',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('phpVers', models.CharField(max_length=5, unique=True)),
],
),
migrations.AddField(
model_name='installedpackages',
name='phpVers',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='managePHP.PHP'),
),
]

View File

@@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2019-01-07 12:43
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('loginSystem', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Package',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('packageName', models.CharField(max_length=50, unique=True)),
('diskSpace', models.IntegerField()),
('bandwidth', models.IntegerField()),
('emailAccounts', models.IntegerField(null=True)),
('dataBases', models.IntegerField(default=0)),
('ftpAccounts', models.IntegerField(default=0)),
('allowedDomains', models.IntegerField(default=0)),
('admin', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='loginSystem.Administrator')),
],
),
]

View File

@@ -8,6 +8,7 @@ from loginSystem.models import Administrator, ACL
from django.shortcuts import HttpResponse from django.shortcuts import HttpResponse
from packages.models import Package from packages.models import Package
from websiteFunctions.models import Websites, ChildDomains from websiteFunctions.models import Websites, ChildDomains
from dockerManager.models import Containers
from dns.models import Domains from dns.models import Domains
import json import json
from subprocess import call, CalledProcessError from subprocess import call, CalledProcessError
@@ -104,6 +105,9 @@ class ACLManager:
finalResponse['manageSSL'] = acl.manageSSL finalResponse['manageSSL'] = acl.manageSSL
finalResponse['hostnameSSL'] = acl.hostnameSSL finalResponse['hostnameSSL'] = acl.hostnameSSL
finalResponse['mailServerSSL'] = acl.mailServerSSL finalResponse['mailServerSSL'] = acl.mailServerSSL
# Container Management
finalResponse['assignContainer'] = acl.assignContainer
return finalResponse return finalResponse
@@ -230,24 +234,6 @@ class ACLManager:
adminNames.append(admin.userName) adminNames.append(admin.userName)
return adminNames return adminNames
@staticmethod
def loadUserObjects(userID):
admin = Administrator.objects.get(pk=userID)
adminObjects = []
finalResponse = ACLManager.loadedACL(userID)
if finalResponse['admin'] == 1:
return Administrator.objects.all()
else:
admins = Administrator.objects.filter(owner=admin.pk)
for items in admins:
adminObjects.append(items)
adminObjects.append(admin)
return adminObjects
@staticmethod @staticmethod
def loadDeletionUsers(userID, finalResponse): def loadDeletionUsers(userID, finalResponse):
admin = Administrator.objects.get(pk=userID) admin = Administrator.objects.get(pk=userID)
@@ -329,15 +315,6 @@ class ACLManager:
return packNames return packNames
@staticmethod
def loadPackageObjects(userID, finalResponse):
admin = Administrator.objects.get(pk=userID)
if finalResponse['admin'] == 1:
return Package.objects.all()
else:
return admin.package_set.all()
@staticmethod @staticmethod
def findAllSites(currentACL, userID): def findAllSites(currentACL, userID):
websiteNames = [] websiteNames = []
@@ -362,6 +339,30 @@ class ACLManager:
return websiteNames return websiteNames
@staticmethod
def findAllContainers(currentACL, userID):
containerName = []
if currentACL['admin'] == 1:
allContainers = Containers.objects.all()
for items in allContainers:
containerName.append(items.name)
else:
admin = Administrator.objects.get(pk=userID)
containers = admin.containers_set.all()
admins = Administrator.objects.filter(owner=admin.pk)
for items in containers:
containerName.append(items.name)
for items in admins:
cons = items.containers_set.all()
for con in cons:
containerName.append(con.name)
return containerName
@staticmethod @staticmethod
def findWebsiteObjects(currentACL, userID): def findWebsiteObjects(currentACL, userID):
@@ -386,6 +387,30 @@ class ACLManager:
websiteList.append(web) websiteList.append(web)
return websiteList return websiteList
@staticmethod
def findContainersObjects(currentACL, userID):
if currentACL['admin'] == 1:
return Containers.objects.all()
else:
containerList = []
admin = Administrator.objects.get(pk=userID)
containers = admin.containers_set.all()
for items in containers:
containerList.append(items)
admins = Administrator.objects.filter(owner=admin.pk)
for items in admins:
cons = items.containers_set.all()
for con in cons:
containerList.append(web)
return containerList
@staticmethod @staticmethod
def findAllDomains(currentACL, userID): def findAllDomains(currentACL, userID):
@@ -437,6 +462,22 @@ class ACLManager:
return 1 return 1
else: else:
return 0 return 0
@staticmethod
def checkContainerOwnership(name, userID):
try:
container = Containers.objects.get(name=name)
currentACL = ACLManager.loadedACL(userID)
admin = Administrator.objects.get(pk=userID)
if currentACL['admin'] == 1:
return 1
elif container.admin == admin:
return 1
else:
return 0
except:
return 0
@staticmethod @staticmethod
def executeCall(command): def executeCall(command):

938
plogical/container.py Normal file
View File

@@ -0,0 +1,938 @@
#!/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 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 django.http import StreamingHttpResponse
from wsgiref.util import FileWrapper
from math import ceil
import docker
import docker.utils
import requests
# Use default socket to connect
client = docker.from_env()
dockerAPI = docker.APIClient()
class ContainerManager:
def __init__(self, name = None):
self.name = name
def submitInstallDocker(self, userID = None, data = None):
try:
currentACL = ACLManager.loadedACL(userID)
if ACLManager.currentContextPermission(currentACL, 'createContainer') == 0:
return ACLManager.loadError()
command = 'yum install -y docker'
cmd = shlex.split(command)
res = subprocess.call(cmd)
if res == 0:
data_ret = {'installDockerStatus': 1, 'error_message': 'None'}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
else:
data_ret = {'installDockerStatus': 0, 'error_message': 'Failed to install. Manual install required.'}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
return HttpResponse(res)
except BaseException, msg:
return HttpResponse(str(msg))
def createContainer(self, request = None, userID = None, data = None):
try:
currentACL = ACLManager.loadedACL(userID)
if ACLManager.currentContextPermission(currentACL, 'createContainer') == 0:
return ACLManager.loadError()
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]
print portConfig
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()
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)
print data['envList']
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:
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('<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,
"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)
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:
currentACL = ACLManager.loadedACL(userID)
if ACLManager.currentContextPermission(currentACL, 'createWebsite') == 0:
return ACLManager.loadErrorJson('createWebSiteStatus', 0)
name = data['name']
image = data['image']
tag = data['tag']
dockerOwner = data['dockerOwner']
memory = data['memory']
envList = data['envList']
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]
## Create Configurations
admin = Administrator.objects.get(userName=dockerOwner)
containerArgs = {'image':image+":"+tag,
'detach':True,
'name':name,
'ports':portConfig,
'publish_all_ports': True,
'environment':envDict}
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),
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:
currentACL = ACLManager.loadedACL(userID)
if ACLManager.currentContextPermission(currentACL, 'createWebsite') == 0:
return ACLManager.loadErrorJson('createWebSiteStatus', 0)
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)
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:
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):
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)
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)
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)
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)
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
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:
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:
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":'asds'})
except BaseException, msg:
return HttpResponse(str(msg))
def manageImages(self, request = None, userID = None, data = None):
try:
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)
tags = []
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']
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:
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:
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']
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
print env
containerArgs = {'image':image+":"+tag,
'detach':True,
'name':name,
'ports':port,
'environment':env,
'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)
memory = data['memory']
startOnReboot = data['startOnReboot']
envList = data['envList']
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']
print envDict
# Prepare data for recreate function
data = {
'name': name,
'unlisted': 0,
'image': con.image,
'tag': con.tag,
'env': envDict,
'ports': json.loads(con.ports), # 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 = {'saveSettingsStatus': 0, 'error_message': str(recreateStatus)}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
con.env = json.dumps(envDict)
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)
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), # 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:
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)

View File

@@ -0,0 +1,94 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2019-01-07 12:43
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('packages', '0001_initial'),
('loginSystem', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='aliasDomains',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('aliasDomain', models.CharField(max_length=75)),
],
),
migrations.CreateModel(
name='Backups',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('fileName', models.CharField(max_length=50)),
('date', models.CharField(max_length=50)),
('size', models.CharField(max_length=50)),
('status', models.IntegerField(default=0)),
],
),
migrations.CreateModel(
name='backupSchedules',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('frequency', models.CharField(max_length=15)),
],
),
migrations.CreateModel(
name='ChildDomains',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('domain', models.CharField(max_length=50, unique=True)),
('path', models.CharField(default=None, max_length=200)),
('ssl', models.IntegerField()),
('phpSelection', models.CharField(default=None, max_length=10)),
],
),
migrations.CreateModel(
name='dest',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('destLoc', models.CharField(max_length=18, unique=True)),
],
),
migrations.CreateModel(
name='Websites',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('domain', models.CharField(max_length=50, unique=True)),
('adminEmail', models.CharField(max_length=50)),
('phpSelection', models.CharField(max_length=10)),
('ssl', models.IntegerField()),
('state', models.IntegerField(default=1)),
('externalApp', models.CharField(default=None, max_length=10)),
('admin', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='loginSystem.Administrator')),
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='packages.Package')),
],
),
migrations.AddField(
model_name='childdomains',
name='master',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='websiteFunctions.Websites'),
),
migrations.AddField(
model_name='backupschedules',
name='dest',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='websiteFunctions.dest'),
),
migrations.AddField(
model_name='backups',
name='website',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='websiteFunctions.Websites'),
),
migrations.AddField(
model_name='aliasdomains',
name='master',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='websiteFunctions.Websites'),
),
]