Added Volume mapping to docker app

This commit is contained in:
Chirag Aggarwal
2019-01-26 18:28:43 +00:00
parent f2dc74edb1
commit 8946c1ce55
9 changed files with 179 additions and 17 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
*.pyc
bin bin

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 = ['*']
@@ -110,15 +110,15 @@ DATABASES = {
'ENGINE': 'django.db.backends.mysql', 'ENGINE': 'django.db.backends.mysql',
'NAME': 'cyberpanel', 'NAME': 'cyberpanel',
'USER': 'cyberpanel', 'USER': 'cyberpanel',
'PASSWORD': 'Bz9gF7Hr7X4RtD', 'PASSWORD': '7Lu8u2NkBwOyWg',
'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': 'Mb5Y9dU2gVb7pM',
'HOST': 'localhost', 'HOST': 'localhost',
'PORT': '', 'PORT': '',
}, },

View File

@@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2019-01-23 18:47
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='Containers',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50, unique=True)),
('cid', models.CharField(default='', max_length=64)),
('image', models.CharField(default='unknown', max_length=50)),
('tag', models.CharField(default='unknown', max_length=50)),
('memory', models.IntegerField(default=0)),
('ports', models.TextField(default='{}')),
('env', models.TextField(default='{}')),
('startOnReboot', models.IntegerField(default=0)),
('admin', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='loginSystem.Administrator')),
],
),
]

View File

@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2019-01-26 16:22
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dockerManager', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='containers',
name='volumes',
field=models.TextField(default='{}'),
),
]

View File

@@ -13,5 +13,6 @@ class Containers(models.Model):
tag = models.CharField(max_length=50, default='unknown') tag = models.CharField(max_length=50, default='unknown')
memory = models.IntegerField(default=0) memory = models.IntegerField(default=0)
ports = models.TextField(default="{}") ports = models.TextField(default="{}")
volumes = models.TextField(default="{}")
env = models.TextField(default="{}") env = models.TextField(default="{}")
startOnReboot = models.IntegerField(default=0) startOnReboot = models.IntegerField(default=0)

View File

@@ -120,6 +120,18 @@ app.controller('runContainer', function ($scope, $http) {
$scope.couldNotConnect = true; $scope.couldNotConnect = true;
$scope.goBackDisable = true; $scope.goBackDisable = true;
$scope.volList = {};
$scope.volListNumber = 0;
$scope.addVolField = function() {
$scope.volList[$scope.volListNumber] = {'dest':'', 'src':''};
$scope.volListNumber = $scope.volListNumber + 1;
console.log($scope.volList)
}
$scope.removeVolField = function(){
delete $scope.volList[$scope.volListNumber - 1];
$scope.volListNumber = $scope.volListNumber - 1;
}
$scope.addEnvField = function () { $scope.addEnvField = function () {
var countEnv = Object.keys($scope.envList).length; var countEnv = Object.keys($scope.envList).length;
$scope.envList[countEnv + 1] = {'name': '', 'value': ''}; $scope.envList[countEnv + 1] = {'name': '', 'value': ''};
@@ -157,8 +169,8 @@ app.controller('runContainer', function ($scope, $http) {
memory: memory, memory: memory,
dockerOwner: dockerOwner, dockerOwner: dockerOwner,
image: image, image: image,
envList: $scope.envList envList: $scope.envList,
volList: $scope.volList
}; };
$.each($scope.portType, function (port, protocol) { $.each($scope.portType, function (port, protocol) {
@@ -699,6 +711,16 @@ app.controller('viewContainer', function ($scope, $http) {
} }
$scope.addVolField = function() {
$scope.volList[$scope.volListNumber] = {'dest':'', 'src':''};
$scope.volListNumber = $scope.volListNumber + 1;
console.log($scope.volList)
}
$scope.removeVolField = function(){
delete $scope.volList[$scope.volListNumber - 1];
$scope.volListNumber = $scope.volListNumber - 1;
}
$scope.saveSettings = function () { $scope.saveSettings = function () {
$('#containerSettingLoading').show(); $('#containerSettingLoading').show();
url = "/docker/saveContainerSettings"; url = "/docker/saveContainerSettings";
@@ -709,7 +731,8 @@ app.controller('viewContainer', function ($scope, $http) {
memory: $scope.memory, memory: $scope.memory,
startOnReboot: $scope.startOnReboot, startOnReboot: $scope.startOnReboot,
envConfirmation: $scope.envConfirmation, envConfirmation: $scope.envConfirmation,
envList: $scope.envList envList: $scope.envList,
volList: $scope.volList
}; };
console.log(data) console.log(data)

View File

@@ -107,11 +107,38 @@
</div> </div>
</div> </div>
<div ng-hide="installationDetailsForm" class="col-md-offset-3"> <div ng-hide="installationDetailsForm" class="col-md-offset-3">
<button type="button" class="btn btn-info" ng-click="addEnvField()">Add more</button> <button type="button" class="btn btn-info" ng-click="addEnvField()">Add more</button>
</div><br> </div><br>
<div ng-hide="installationDetailsForm" class="form-group text-center">
<label class="control-label">
{% trans "Map Volumes" %}
</label>
</div>
<div ng-repeat="volume in volList track by $index">
<div ng-hide="installationDetailsForm" class="form-group">
<div class="col-sm-3"></div>
<div class="col-sm-2">
<input type="text" class="form-control" ng-model="volList[$index].dest" placeholder="Destination" required>
</div>
<div class="col-sm-4">
<input type="text" class="form-control" ng-model="volList[$index].src" placeholder="Source" required>
</div>
<div ng-show="$last">
<div class="col-sm-1">
<button class="btn btn-primary" type="button" ng-click="removeVolField()"><i class="fa fa-times"></i></button>
</div>
</div>
</div>
</div>
<div ng-hide="installationDetailsForm" class="text-center">
<button type="button" class="btn btn-info" ng-click="addVolField()">{% trans "Add field" %}</button>
</div><br>
<div ng-hide="installationDetailsForm" class="form-group"> <div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label"></label> <label class="col-sm-3 control-label"></label>
<div class="col-sm-4"> <div class="col-sm-4">

View File

@@ -210,12 +210,12 @@
<div class="checkbox"> <div class="checkbox">
<label> <label>
<input ng-model="envConfirmation" type="checkbox"> <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> Editing ENV or Volume 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> </label>
</div> </div>
</div> </div>
</div> </div>
<hr>
<span ng-init="envList = {}"></span> <span ng-init="envList = {}"></span>
{% for env, value in envList.items %} {% for env, value in envList.items %}
@@ -245,6 +245,43 @@
<button type="button" class="btn btn-info" ng-click="addEnvField()">Add more</button> <button type="button" class="btn btn-info" ng-click="addEnvField()">Add more</button>
</div><br> </div><br>
<span ng-init="volList = {}"></span>
{% for key, value in volList.items %}
<span ng-init="volList[{{ forloop.counter0 }}] = {'dest':'{{value.bind}}' , 'src':'{{key}}'}"></span>
<span ng-init="volListNumber={{ forloop.counter0 }} + 1"></span>
{% endfor %}
<hr>
<div ng-hide="installationDetailsForm" class="form-group text-center">
<label class="control-label">
{% trans "Map Volumes" %}
</label>
</div>
<div ng-repeat="volume in volList track by $index">
<div ng-hide="installationDetailsForm" class="form-group">
<div class="col-sm-3"></div>
<div class="col-sm-2">
<input type="text" class="form-control" ng-model="volList[$index].dest" placeholder="Destination" required>
</div>
<div class="col-sm-4">
<input type="text" class="form-control" ng-model="volList[$index].src" placeholder="Source" required>
</div>
<div ng-show="$last">
<div class="col-sm-1">
<button class="btn btn-primary" type="button" ng-click="removeVolField()"><i class="fa fa-times"></i></button>
</div>
</div>
</div>
</div>
<div ng-hide="installationDetailsForm" class="text-center">
<button type="button" class="btn btn-info" ng-click="addVolField()">{% trans "Add field" %}</button>
</div><br>
</form> </form>
</div> </div>

View File

@@ -182,7 +182,7 @@ class ContainerManager(multi.Thread):
data['ports'] = json.loads(con.ports) data['ports'] = json.loads(con.ports)
data['cid'] = con.cid data['cid'] = con.cid
data['envList'] = json.loads(con.env) data['envList'] = json.loads(con.env)
print data['envList'] data['volList'] = json.loads(con.volumes)
stats = container.stats(decode=False, stream=False) stats = container.stats(decode=False, stream=False)
logs = container.logs(stream=True) logs = container.logs(stream=True)
@@ -300,6 +300,7 @@ class ContainerManager(multi.Thread):
dockerOwner = data['dockerOwner'] dockerOwner = data['dockerOwner']
memory = data['memory'] memory = data['memory']
envList = data['envList'] envList = data['envList']
volList = data['volList']
inspectImage = dockerAPI.inspect_image(image + ":" + tag) inspectImage = dockerAPI.inspect_image(image + ":" + tag)
portConfig = {} portConfig = {}
@@ -319,6 +320,12 @@ class ContainerManager(multi.Thread):
return HttpResponse(json_data) return HttpResponse(json_data)
portConfig[item] = data[item] portConfig[item] = data[item]
volumes = {}
for index, volume in volList.iteritems():
volumes[volume['src']] = {'bind': volume['dest'],
'mode': 'rw'}
print volumes
## Create Configurations ## Create Configurations
admin = Administrator.objects.get(userName=dockerOwner) admin = Administrator.objects.get(userName=dockerOwner)
@@ -327,7 +334,8 @@ class ContainerManager(multi.Thread):
'name': name, 'name': name,
'ports': portConfig, 'ports': portConfig,
'publish_all_ports': True, 'publish_all_ports': True,
'environment': envDict} 'environment': envDict,
'volumes': volumes}
containerArgs['mem_limit'] = memory * 1048576; # Converts MB to bytes ( 0 * x = 0 for unlimited memory) containerArgs['mem_limit'] = memory * 1048576; # Converts MB to bytes ( 0 * x = 0 for unlimited memory)
@@ -347,6 +355,7 @@ class ContainerManager(multi.Thread):
image=image, image=image,
memory=memory, memory=memory,
ports=json.dumps(portConfig), ports=json.dumps(portConfig),
volumes=json.dumps(volumes),
env=json.dumps(envDict), env=json.dumps(envDict),
cid=container.id) cid=container.id)
@@ -881,11 +890,16 @@ class ContainerManager(multi.Thread):
def doRecreateContainer(self, userID, data, con): def doRecreateContainer(self, userID, data, con):
try: try:
client = docker.from_env()
dockerAPI = docker.APIClient()
name = data['name'] name = data['name']
unlisted = data['unlisted'] # Pass this as 1 if image is not known for container unlisted = data['unlisted'] # Pass this as 1 if image is not known for container
image = data['image'] image = data['image']
tag = data['tag'] tag = data['tag']
env = data['env'] env = data['env']
volumes = data['volumes']
port = data['ports'] port = data['ports']
memory = data['memory'] memory = data['memory']
@@ -902,6 +916,7 @@ class ContainerManager(multi.Thread):
'name': name, 'name': name,
'ports': port, 'ports': port,
'environment': env, 'environment': env,
'volumes': volumes,
'publish_all_ports': True, 'publish_all_ports': True,
'mem_limit': memory * 1048576} 'mem_limit': memory * 1048576}
@@ -928,6 +943,7 @@ class ContainerManager(multi.Thread):
memory = data['memory'] memory = data['memory']
startOnReboot = data['startOnReboot'] startOnReboot = data['startOnReboot']
envList = data['envList'] envList = data['envList']
volList = data['volList']
if startOnReboot == True: if startOnReboot == True:
startOnReboot = 1 startOnReboot = 1
@@ -966,7 +982,10 @@ class ContainerManager(multi.Thread):
if (value['name'] != '') or (value['value'] != ''): if (value['name'] != '') or (value['value'] != ''):
envDict[value['name']] = value['value'] envDict[value['name']] = value['value']
print envDict volumes = {}
for index, volume in volList.iteritems():
volumes[volume['src']] = {'bind': volume['dest'],
'mode': 'rw'}
# Prepare data for recreate function # Prepare data for recreate function
data = { data = {
'name': name, 'name': name,
@@ -975,7 +994,7 @@ class ContainerManager(multi.Thread):
'tag': con.tag, 'tag': con.tag,
'env': envDict, 'env': envDict,
'ports': json.loads(con.ports), 'ports': json.loads(con.ports),
# No filter needed now as its ports are filtered when adding to database 'volumes': volumes,
'memory': con.memory 'memory': con.memory
} }
@@ -986,6 +1005,7 @@ class ContainerManager(multi.Thread):
return HttpResponse(json_data) return HttpResponse(json_data)
con.env = json.dumps(envDict) con.env = json.dumps(envDict)
con.volumes = json.dumps(volumes)
con.save() con.save()
data_ret = {'saveSettingsStatus': 1, 'error_message': 'None'} data_ret = {'saveSettingsStatus': 1, 'error_message': 'None'}