mirror of
				https://github.com/retspen/webvirtcloud
				synced 2025-07-31 12:41:08 +00:00 
			
		
		
		
	Add app
This commit is contained in:
		
							parent
							
								
									fa3df5bff3
								
							
						
					
					
						commit
						7dee5b94ac
					
				
					 23 changed files with 727 additions and 31 deletions
				
			
		
							
								
								
									
										0
									
								
								console/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								console/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										3
									
								
								console/admin.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								console/admin.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
from django.contrib import admin
 | 
			
		||||
 | 
			
		||||
# Register your models here.
 | 
			
		||||
							
								
								
									
										0
									
								
								console/migrations/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								console/migrations/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										3
									
								
								console/models.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								console/models.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
from django.db import models
 | 
			
		||||
 | 
			
		||||
# Create your models here.
 | 
			
		||||
							
								
								
									
										3
									
								
								console/tests.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								console/tests.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
from django.test import TestCase
 | 
			
		||||
 | 
			
		||||
# Create your tests here.
 | 
			
		||||
							
								
								
									
										56
									
								
								console/views.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								console/views.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,56 @@
 | 
			
		|||
import re
 | 
			
		||||
from django.shortcuts import render
 | 
			
		||||
from django.http import HttpResponseRedirect
 | 
			
		||||
from django.core.urlresolvers import reverse
 | 
			
		||||
from instances.models import Instance
 | 
			
		||||
from vrtManager.instance import wvmInstance
 | 
			
		||||
from webvirtcloud.settings import WS_PORT
 | 
			
		||||
from webvirtcloud.settings import WS_PUBLIC_HOST
 | 
			
		||||
from libvirt import libvirtError
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def console(request):
 | 
			
		||||
    """
 | 
			
		||||
    :param request:
 | 
			
		||||
    :return:
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    if not request.user.is_authenticated():
 | 
			
		||||
        return HttpResponseRedirect(reverse('login'))
 | 
			
		||||
 | 
			
		||||
    if request.method == 'GET':
 | 
			
		||||
        token = request.GET.get('token', '')
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        temptoken = token.split('-', 1)
 | 
			
		||||
        host = int(temptoken[0])
 | 
			
		||||
        uuid = temptoken[1]
 | 
			
		||||
        instance = Instance.objects.get(compute_id=host, uuid=uuid)
 | 
			
		||||
        conn = wvmInstance(instance.compute.hostname,
 | 
			
		||||
                           instance.compute.login,
 | 
			
		||||
                           instance.compute.password,
 | 
			
		||||
                           instance.compute.type,
 | 
			
		||||
                           instance.name)
 | 
			
		||||
        console_type = conn.get_console_type()
 | 
			
		||||
        console_websocket_port = conn.get_console_websocket_port()
 | 
			
		||||
        console_passwd = conn.get_console_passwd()
 | 
			
		||||
    except libvirtError as lib_err:
 | 
			
		||||
        console_type = None
 | 
			
		||||
        console_websocket_port = None
 | 
			
		||||
        console_passwd = None
 | 
			
		||||
 | 
			
		||||
    ws_port = console_websocket_port if console_websocket_port else WS_PORT
 | 
			
		||||
    ws_host = WS_PUBLIC_HOST if WS_PUBLIC_HOST else request.get_host()
 | 
			
		||||
 | 
			
		||||
    if ':' in ws_host:
 | 
			
		||||
        ws_host = re.sub(':[0-9]+', '', ws_host)
 | 
			
		||||
 | 
			
		||||
    if console_type == 'vnc':
 | 
			
		||||
        response = render(request, 'console-vnc.html', locals())
 | 
			
		||||
    elif console_type == 'spice':
 | 
			
		||||
        response = render(request, 'console-spice.html', locals())
 | 
			
		||||
    else:
 | 
			
		||||
        response = "Console type %s no support" % console_type
 | 
			
		||||
 | 
			
		||||
    response.set_cookie('token', token)
 | 
			
		||||
    return response
 | 
			
		||||
							
								
								
									
										0
									
								
								definst/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								definst/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										3
									
								
								definst/admin.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								definst/admin.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
from django.contrib import admin
 | 
			
		||||
 | 
			
		||||
# Register your models here.
 | 
			
		||||
							
								
								
									
										55
									
								
								definst/forms.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								definst/forms.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,55 @@
 | 
			
		|||
import re
 | 
			
		||||
from django import forms
 | 
			
		||||
from django.utils.translation import ugettext_lazy as _
 | 
			
		||||
from definst.models import Flavor
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FlavorAddForm(forms.Form):
 | 
			
		||||
    label = forms.CharField(label="Name",
 | 
			
		||||
                            error_messages={'required': _('No flavor name has been entered')},
 | 
			
		||||
                            max_length=20)
 | 
			
		||||
    vcpu = forms.IntegerField(label="VCPU",
 | 
			
		||||
                              error_messages={'required': _('No VCPU has been entered')}, )
 | 
			
		||||
    disk = forms.IntegerField(label="HDD",
 | 
			
		||||
                              error_messages={'required': _('No HDD image has been entered')}, )
 | 
			
		||||
    memory = forms.IntegerField(label="RAM",
 | 
			
		||||
                                error_messages={'required': _('No RAM size has been entered')}, )
 | 
			
		||||
 | 
			
		||||
    def clean_name(self):
 | 
			
		||||
        label = self.cleaned_data['label']
 | 
			
		||||
        have_symbol = re.match('^[a-zA-Z0-9._-]+$', label)
 | 
			
		||||
        if not have_symbol:
 | 
			
		||||
            raise forms.ValidationError(_('The flavor name must not contain any special characters'))
 | 
			
		||||
        elif len(label) > 20:
 | 
			
		||||
            raise forms.ValidationError(_('The flavor name must not exceed 20 characters'))
 | 
			
		||||
        try:
 | 
			
		||||
            Flavor.objects.get(label=label)
 | 
			
		||||
        except Flavor.DoesNotExist:
 | 
			
		||||
            return label
 | 
			
		||||
        raise forms.ValidationError(_('Flavor name is already use'))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class NewVMForm(forms.Form):
 | 
			
		||||
    name = forms.CharField(error_messages={'required': _('No Virtual Machine name has been entered')},
 | 
			
		||||
                           max_length=20)
 | 
			
		||||
    vcpu = forms.IntegerField(error_messages={'required': _('No VCPU has been entered')})
 | 
			
		||||
    host_model = forms.BooleanField(required=False)
 | 
			
		||||
    disk = forms.IntegerField(required=False)
 | 
			
		||||
    memory = forms.IntegerField(error_messages={'required': _('No RAM size has been entered')})
 | 
			
		||||
    networks = forms.CharField(error_messages={'required': _('No Network pool has been choice')})
 | 
			
		||||
    storage = forms.CharField(max_length=20, required=False)
 | 
			
		||||
    template = forms.CharField(required=False)
 | 
			
		||||
    images = forms.CharField(required=False)
 | 
			
		||||
    hdd_size = forms.IntegerField(required=False)
 | 
			
		||||
    meta_prealloc = forms.BooleanField(required=False)
 | 
			
		||||
    virtio = forms.BooleanField(required=False)
 | 
			
		||||
    mac = forms.CharField(required=False)
 | 
			
		||||
 | 
			
		||||
    def clean_name(self):
 | 
			
		||||
        name = self.cleaned_data['name']
 | 
			
		||||
        have_symbol = re.match('^[a-zA-Z0-9._-]+$', name)
 | 
			
		||||
        if not have_symbol:
 | 
			
		||||
            raise forms.ValidationError(_('The name of the virtual machine must not contain any special characters'))
 | 
			
		||||
        elif len(name) > 20:
 | 
			
		||||
            raise forms.ValidationError(_('The name of the virtual machine must not exceed 20 characters'))
 | 
			
		||||
        return name
 | 
			
		||||
							
								
								
									
										0
									
								
								definst/migrations/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								definst/migrations/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										11
									
								
								definst/models.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								definst/models.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
from django.db import models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Flavor(models.Model):
 | 
			
		||||
    label = models.CharField(max_length=12)
 | 
			
		||||
    memory = models.IntegerField()
 | 
			
		||||
    vcpu = models.IntegerField()
 | 
			
		||||
    disk = models.IntegerField()
 | 
			
		||||
 | 
			
		||||
    def __unicode__(self):
 | 
			
		||||
        return self.name
 | 
			
		||||
							
								
								
									
										3
									
								
								definst/tests.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								definst/tests.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
from django.test import TestCase
 | 
			
		||||
 | 
			
		||||
# Create your tests here.
 | 
			
		||||
							
								
								
									
										136
									
								
								definst/views.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								definst/views.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,136 @@
 | 
			
		|||
from django.shortcuts import render
 | 
			
		||||
from django.http import HttpResponseRedirect
 | 
			
		||||
from django.utils.translation import ugettext_lazy as _
 | 
			
		||||
from django.core.urlresolvers import reverse
 | 
			
		||||
from computes.models import Compute
 | 
			
		||||
from definst.models import Flavor
 | 
			
		||||
from definst.forms import FlavorAddForm, NewVMForm
 | 
			
		||||
from instances.models import Instance
 | 
			
		||||
from vrtManager.create import wvmCreate
 | 
			
		||||
from vrtManager import util
 | 
			
		||||
from libvirt import libvirtError
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def create(request, host_id):
 | 
			
		||||
    """
 | 
			
		||||
    :param request:
 | 
			
		||||
    :return:
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    if not request.user.is_authenticated():
 | 
			
		||||
        return HttpResponseRedirect(reverse('index'))
 | 
			
		||||
 | 
			
		||||
    conn = None
 | 
			
		||||
    error_messages = []
 | 
			
		||||
    storages = []
 | 
			
		||||
    networks = []
 | 
			
		||||
    meta_prealloc = False
 | 
			
		||||
    compute = Compute.objects.get(id=host_id)
 | 
			
		||||
    flavors = Flavor.objects.filter().order_by('id')
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        conn = wvmCreate(compute.hostname,
 | 
			
		||||
                         compute.login,
 | 
			
		||||
                         compute.password,
 | 
			
		||||
                         compute.type)
 | 
			
		||||
 | 
			
		||||
        storages = sorted(conn.get_storages())
 | 
			
		||||
        networks = sorted(conn.get_networks())
 | 
			
		||||
        instances = conn.get_instances()
 | 
			
		||||
        get_images = sorted(conn.get_storages_images())
 | 
			
		||||
        mac_auto = util.randomMAC()
 | 
			
		||||
    except libvirtError as lib_err:
 | 
			
		||||
        error_messages.append(lib_err)
 | 
			
		||||
 | 
			
		||||
    if conn:
 | 
			
		||||
        if not storages:
 | 
			
		||||
            msg = _("You haven't defined have any storage pools")
 | 
			
		||||
            error_messages.append(msg)
 | 
			
		||||
        if not networks:
 | 
			
		||||
            msg = _("You haven't defined have any network pools")
 | 
			
		||||
            error_messages.append(msg)
 | 
			
		||||
 | 
			
		||||
        if request.method == 'POST':
 | 
			
		||||
            if 'create_flavor' in request.POST:
 | 
			
		||||
                form = FlavorAddForm(request.POST)
 | 
			
		||||
                if form.is_valid():
 | 
			
		||||
                    data = form.cleaned_data
 | 
			
		||||
                    create_flavor = Flavor(label=data['label'],
 | 
			
		||||
                                           vcpu=data['vcpu'],
 | 
			
		||||
                                           memory=data['memory'],
 | 
			
		||||
                                           disk=data['disk'])
 | 
			
		||||
                    create_flavor.save()
 | 
			
		||||
                    return HttpResponseRedirect(request.get_full_path())
 | 
			
		||||
            if 'delete_flavor' in request.POST:
 | 
			
		||||
                flavor_id = request.POST.get('flavor', '')
 | 
			
		||||
                delete_flavor = Flavor.objects.get(id=flavor_id)
 | 
			
		||||
                delete_flavor.delete()
 | 
			
		||||
                return HttpResponseRedirect(request.get_full_path())
 | 
			
		||||
            if 'create_xml' in request.POST:
 | 
			
		||||
                xml = request.POST.get('from_xml', '')
 | 
			
		||||
                try:
 | 
			
		||||
                    name = util.get_xml_path(xml, '/domain/name')
 | 
			
		||||
                except util.libxml2.parserError:
 | 
			
		||||
                    name = None
 | 
			
		||||
                if name in instances:
 | 
			
		||||
                    error_msg = _("A virtual machine with this name already exists")
 | 
			
		||||
                    error_messages.append(error_msg)
 | 
			
		||||
                else:
 | 
			
		||||
                    try:
 | 
			
		||||
                        conn._defineXML(xml)
 | 
			
		||||
                        return HttpResponseRedirect(reverse('instance', args=[host_id, name]))
 | 
			
		||||
                    except libvirtError as lib_err:
 | 
			
		||||
                        error_messages.append(lib_err.message)
 | 
			
		||||
            if 'create' in request.POST:
 | 
			
		||||
                volumes = {}
 | 
			
		||||
                form = NewVMForm(request.POST)
 | 
			
		||||
                if form.is_valid():
 | 
			
		||||
                    data = form.cleaned_data
 | 
			
		||||
                    if data['meta_prealloc']:
 | 
			
		||||
                        meta_prealloc = True
 | 
			
		||||
                    if instances:
 | 
			
		||||
                        if data['name'] in instances:
 | 
			
		||||
                            msg = _("A virtual machine with this name already exists")
 | 
			
		||||
                            error_messages.append(msg)
 | 
			
		||||
                    if not error_messages:
 | 
			
		||||
                        if data['hdd_size']:
 | 
			
		||||
                            if not data['mac']:
 | 
			
		||||
                                error_msg = _("No Virtual Machine MAC has been entered")
 | 
			
		||||
                                error_messages.append(error_msg)
 | 
			
		||||
                            else:
 | 
			
		||||
                                try:
 | 
			
		||||
                                    path = conn.create_volume(data['storage'], data['name'], data['hdd_size'],
 | 
			
		||||
                                                              metadata=meta_prealloc)
 | 
			
		||||
                                    volumes[path] = conn.get_volume_type(path)
 | 
			
		||||
                                except libvirtError as lib_err:
 | 
			
		||||
                                    error_messages.append(lib_err.message)
 | 
			
		||||
                        elif data['template']:
 | 
			
		||||
                            templ_path = conn.get_volume_path(data['template'])
 | 
			
		||||
                            clone_path = conn.clone_from_template(data['name'], templ_path, metadata=meta_prealloc)
 | 
			
		||||
                            volumes[clone_path] = conn.get_volume_type(clone_path)
 | 
			
		||||
                        else:
 | 
			
		||||
                            if not data['images']:
 | 
			
		||||
                                error_msg = _("First you need to create or select an image")
 | 
			
		||||
                                error_messages.append(error_msg)
 | 
			
		||||
                            else:
 | 
			
		||||
                                for vol in data['images'].split(','):
 | 
			
		||||
                                    try:
 | 
			
		||||
                                        path = conn.get_volume_path(vol)
 | 
			
		||||
                                        volumes[path] = conn.get_volume_type(path)
 | 
			
		||||
                                    except libvirtError as lib_err:
 | 
			
		||||
                                        error_messages.append(lib_err.message)
 | 
			
		||||
                        if not error_messages:
 | 
			
		||||
                            uuid = util.randomUUID()
 | 
			
		||||
                            try:
 | 
			
		||||
                                conn.create_instance(data['name'], data['memory'], data['vcpu'], data['host_model'],
 | 
			
		||||
                                                     uuid, volumes, data['networks'], data['virtio'], data['mac'])
 | 
			
		||||
                                create_instance = Instance(compute_id=host_id, name=data['name'], uuid=uuid)
 | 
			
		||||
                                create_instance.save()
 | 
			
		||||
                                return HttpResponseRedirect(reverse('instance', args=[host_id, data['name']]))
 | 
			
		||||
                            except libvirtError as lib_err:
 | 
			
		||||
                                if data['hdd_size']:
 | 
			
		||||
                                    conn.delete_volume(volumes.keys()[0])
 | 
			
		||||
                                error_messages.append(lib_err)
 | 
			
		||||
        conn.close()
 | 
			
		||||
 | 
			
		||||
    return render('definst.html', locals())
 | 
			
		||||
							
								
								
									
										15
									
								
								templates/404.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								templates/404.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
{% extends "base.html" %}
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
{% block title %}{% trans "404" %}{% endblock %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
    <div class="row">
 | 
			
		||||
        <div class="col-xs-12" id="error">
 | 
			
		||||
            <h1>Oops!</h1>
 | 
			
		||||
 | 
			
		||||
            <p class="lead">{% trans "404 Not Found" %}</p>
 | 
			
		||||
 | 
			
		||||
            <p>{% trans "The requested page was not found on this server." %}</p>
 | 
			
		||||
            <a class="btn btn-medium btn-success" href="javascript:history.back()">← Back</a>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
							
								
								
									
										15
									
								
								templates/500.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								templates/500.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
{% extends "base.html" %}
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
{% block title %}{% trans "500" %}{% endblock %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
    <div class="row">
 | 
			
		||||
        <div class="col-xs-12" id="error">
 | 
			
		||||
            <h1>Oops!</h1>
 | 
			
		||||
 | 
			
		||||
            <p class="lead">{% trans "500 Internal Server Error" %}</p>
 | 
			
		||||
 | 
			
		||||
            <p>{% trans "The server encountered an internal error or misconfiguration and was unable to complete you request." %}</p>
 | 
			
		||||
            <a class="btn btn-medium btn-success" href="javascript:history.back()">← Back</a>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
| 
						 | 
				
			
			@ -5,13 +5,16 @@
 | 
			
		|||
    <meta charset="utf-8">
 | 
			
		||||
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
			
		||||
 | 
			
		||||
    <title>{% block title %}{% endblock %}</title>
 | 
			
		||||
 | 
			
		||||
    <link rel="icon" href="{% static "favicon.ico" %}">
 | 
			
		||||
 | 
			
		||||
    <title>Dashboard Template for Bootstrap</title>
 | 
			
		||||
 | 
			
		||||
    <!-- Bootstrap core CSS -->
 | 
			
		||||
    <link href="{% static "css/bootstrap.min.css" %}" rel="stylesheet">
 | 
			
		||||
 | 
			
		||||
    <!-- Custom styles for this template -->
 | 
			
		||||
    <link href="{% static "css/dashboard.css" %}" rel="stylesheet">
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
    {% block content %}{% endblock %}
 | 
			
		||||
    <script src="{% static "js/jquery.min.js" %}"></script>
 | 
			
		||||
    <script src="{% static "js/bootstrap.min.js" %}"></script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
{% load static %}
 | 
			
		||||
{% extends "base.html" %}
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
{% include 'header.html' %}
 | 
			
		||||
<body>
 | 
			
		||||
{% block title %}{% trans "Compute" %} - {{ compute.name }}{% endblock %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
<div class="container-fluid">
 | 
			
		||||
    <div class="row">
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -53,5 +53,4 @@
 | 
			
		|||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
{% include 'footer.html' %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
{% load static %}
 | 
			
		||||
{% extends "base.html" %}
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
{% include 'header.html' %}
 | 
			
		||||
<body>
 | 
			
		||||
{% block title %}{% trans "Computes" %}{% endblock %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
<div class="container-fluid">
 | 
			
		||||
    <div class="row">
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -227,5 +227,4 @@
 | 
			
		|||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
{% include 'footer.html' %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
							
								
								
									
										208
									
								
								templates/console-spice.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								templates/console-spice.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,208 @@
 | 
			
		|||
{% load i18n %}
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
    <link rel="shortcut icon" href="{{ STATIC_URL }}img/favicon.ico">
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/spicearraybuffer.js"></script> 
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/enums.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/atKeynames.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/utils.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/png.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/lz.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/quic.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/bitmap.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/spicedataview.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/spicetype.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/spicemsg.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/wire.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/spiceconn.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/display.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/main.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/inputs.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/webm.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/playback.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/simulatecursor.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/cursor.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/thirdparty/jsbn.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/thirdparty/rsa.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/thirdparty/prng4.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/thirdparty/rng.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/thirdparty/sha1.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/ticket.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/resize.js"></script>
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/spice-html5/filexfer.js"></script>
 | 
			
		||||
 | 
			
		||||
    <style>
 | 
			
		||||
        body {
 | 
			
		||||
            margin: 0;
 | 
			
		||||
            padding: 0;
 | 
			
		||||
            font-family: Helvetica;
 | 
			
		||||
            background-color:#494949;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        #status {
 | 
			
		||||
            text-align: center;
 | 
			
		||||
            width: 100%;
 | 
			
		||||
            margin: 0;
 | 
			
		||||
            font-size: 1em;
 | 
			
		||||
            height: 1.6em;
 | 
			
		||||
            padding-top: 0.3em;
 | 
			
		||||
            background-color: #222;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        #spice-area {
 | 
			
		||||
            border-bottom-right-radius: 800px 600px;
 | 
			
		||||
            background-color: #313131;
 | 
			
		||||
            height: 100%;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #spice-screen canvas {
 | 
			
		||||
            padding-left: 0;
 | 
			
		||||
            padding-right: 0;
 | 
			
		||||
            margin-left: auto;
 | 
			
		||||
            margin-right: auto;
 | 
			
		||||
            display: block;
 | 
			
		||||
        }
 | 
			
		||||
    </style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
    <div id="status"></div>
 | 
			
		||||
        <div id="spice-area">
 | 
			
		||||
            <div id="spice-screen" class="spice-screen"></div>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <script>
 | 
			
		||||
            var sc;
 | 
			
		||||
 | 
			
		||||
            function spice_set_cookie(name, value, days) {
 | 
			
		||||
                var date, expires;
 | 
			
		||||
                date = new Date();
 | 
			
		||||
                date.setTime(date.getTime() + (days*24*60*60*1000));
 | 
			
		||||
                expires = "; expires=" + date.toGMTString();
 | 
			
		||||
                document.cookie = name + "=" + value + expires + "; path=/";
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            function spice_query_var(name, defvalue) {
 | 
			
		||||
                var match = RegExp('[?&]' + name + '=([^&]*)')
 | 
			
		||||
                                  .exec(window.location.search);
 | 
			
		||||
                return match ?
 | 
			
		||||
                    decodeURIComponent(match[1].replace(/\+/g, ' '))
 | 
			
		||||
                    : defvalue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var status_div=false;
 | 
			
		||||
            function log_message(msg,color,bgcolor) {
 | 
			
		||||
                if (!status_div) {
 | 
			
		||||
                    status_div=document.getElementById('status');
 | 
			
		||||
                }
 | 
			
		||||
                status_div.innerHTML=msg;
 | 
			
		||||
                if (color) {
 | 
			
		||||
                    status_div.style.color=color;
 | 
			
		||||
                }
 | 
			
		||||
                if (bgcolor) {
 | 
			
		||||
                    status_div.style.backgroundColor=bgcolor;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            function log_error(msg) {
 | 
			
		||||
                log_message(msg,'#000','#f44');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            function log_info(msg) {
 | 
			
		||||
                log_message(msg,'#000','#eee');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            function spice_error(e)
 | 
			
		||||
            {
 | 
			
		||||
                console.log(e);
 | 
			
		||||
                disconnect();
 | 
			
		||||
                if (e.message != undefined) {
 | 
			
		||||
                    log_error(e.message);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    log_error('Unknown error');
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            function spice_success(msg) {
 | 
			
		||||
                log_info(msg);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            function connect(uri,password)
 | 
			
		||||
            {
 | 
			
		||||
                // If a token variable is passed in, set the parameter in a cookie.
 | 
			
		||||
                // This is used by nova-spiceproxy.
 | 
			
		||||
                token = spice_query_var('token', null);
 | 
			
		||||
                if (token) {
 | 
			
		||||
                    spice_set_cookie('token', token, 1)
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (sc) {
 | 
			
		||||
                    sc.stop();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    sc = new SpiceMainConn({uri: uri, password: password, screen_id: "spice-screen",
 | 
			
		||||
                                onsuccess: spice_success, onerror: spice_error, onagent: agent_connected });
 | 
			
		||||
                }
 | 
			
		||||
                catch (e)
 | 
			
		||||
                {
 | 
			
		||||
                    console.log(e);
 | 
			
		||||
                    log_error(e.toString());
 | 
			
		||||
                    disconnect();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            function disconnect()
 | 
			
		||||
            {
 | 
			
		||||
                console.log(">> disconnect");
 | 
			
		||||
                if (sc) {
 | 
			
		||||
                    sc.stop();
 | 
			
		||||
                }
 | 
			
		||||
                if (window.File && window.FileReader && window.FileList && window.Blob)
 | 
			
		||||
                {
 | 
			
		||||
                    console.log(" -> Disable drag/drop transfer");
 | 
			
		||||
                    var spice_xfer_area = document.getElementById('spice-xfer-area');
 | 
			
		||||
                    try {
 | 
			
		||||
                        document.getElementById('spice-area').removeChild(spice_xfer_area);
 | 
			
		||||
                        document.getElementById('spice-area').removeEventListener('dragover', handle_file_dragover, false);
 | 
			
		||||
                        document.getElementById('spice-area').removeEventListener('drop', handle_file_drop, false);
 | 
			
		||||
                    }
 | 
			
		||||
                    catch(e) {
 | 
			
		||||
                        console.log(' -> Error disabling drag/drop transfer');
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                console.log("<< disconnect");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            function agent_connected(sc) {
 | 
			
		||||
                console.log('Connected');
 | 
			
		||||
                window.addEventListener('resize', handle_resize);
 | 
			
		||||
                window.spice_connection = this;
 | 
			
		||||
 | 
			
		||||
                resize_helper(this);
 | 
			
		||||
 | 
			
		||||
                if (window.File && window.FileReader && window.FileList && window.Blob)
 | 
			
		||||
                {
 | 
			
		||||
                    var spice_xfer_area = document.createElement("div");
 | 
			
		||||
                    spice_xfer_area.setAttribute('id', 'spice-xfer-area');
 | 
			
		||||
                    document.getElementById('spice-area').addEventListener('dragover', handle_file_dragover, false);
 | 
			
		||||
                    document.getElementById('spice-area').addEventListener('drop', handle_file_drop, false);
 | 
			
		||||
                    log_info('Drag and drop transfer enabled.');
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    console.log("File API is not supported");
 | 
			
		||||
                    log_info('Drag and drop transfer not supported.');
 | 
			
		||||
                }
 | 
			
		||||
                log_info('Connected');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var uri = 'ws://{{ ws_host }}:{{ ws_port }}';
 | 
			
		||||
            var password = '{{ console_passwd }}';
 | 
			
		||||
            log_info('Connecting ...');
 | 
			
		||||
            connect(uri,password);
 | 
			
		||||
        </script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										186
									
								
								templates/console-vnc.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								templates/console-vnc.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,186 @@
 | 
			
		|||
{% load i18n %}
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
    <link rel="shortcut icon" href="{{ STATIC_URL }}img/favicon.ico">
 | 
			
		||||
    <link rel="stylesheet" href="{{ STATIC_URL }}js/novnc/base.css" title="plain">
 | 
			
		||||
    <!--
 | 
			
		||||
    <script type='text/javascript'
 | 
			
		||||
        src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
 | 
			
		||||
    -->
 | 
			
		||||
    <script src="{{ STATIC_URL }}js/novnc/util.js"></script>
 | 
			
		||||
</head>
 | 
			
		||||
<body style="margin: 0px;">
 | 
			
		||||
<div id="noVNC_screen">
 | 
			
		||||
    <div id="noVNC_status_bar" class="noVNC_status_bar" style="margin-top: 0px;">
 | 
			
		||||
        <table border=0 width="100%">
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <div id="noVNC_status">{% trans "Loading..." %}</div>
 | 
			
		||||
                </td>
 | 
			
		||||
                <td width="18%" style="text-align:right;">
 | 
			
		||||
                    <div id="noVNC_buttons">
 | 
			
		||||
                        <!-- dirty fix for keyboard on iOS devices -->
 | 
			
		||||
                        <input type="button" id="showKeyboard" value="Keyboard" title="Show Keyboard"/>
 | 
			
		||||
                        <!-- Note that Google Chrome on Android doesn't respect any of these,
 | 
			
		||||
                        html attributes which attempt to disable text suggestions on the
 | 
			
		||||
                        on-screen keyboard. Let's hope Chrome implements the ime-mode
 | 
			
		||||
                        style for example -->
 | 
			
		||||
                        <!-- TODO: check if this is needed on iOS -->
 | 
			
		||||
                        <textarea id="keyboardinput" autocapitalize="off"
 | 
			
		||||
                                  autocorrect="off" autocomplete="off" spellcheck="false"
 | 
			
		||||
                                  mozactionhint="Enter" onsubmit="return false;"
 | 
			
		||||
                                  style="ime-mode: disabled;">
 | 
			
		||||
                        </textarea>
 | 
			
		||||
 | 
			
		||||
                        <input type=button value="Ctrl+Alt+Del" id="sendCtrlAltDelButton">
 | 
			
		||||
                    </div>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </table>
 | 
			
		||||
    </div>
 | 
			
		||||
    <canvas id="noVNC_canvas" width="640px" height="20px">
 | 
			
		||||
        {% trans "Canvas not supported." %}
 | 
			
		||||
    </canvas>
 | 
			
		||||
</div>
 | 
			
		||||
<script>
 | 
			
		||||
    /*jslint white: false */
 | 
			
		||||
    /*global window, $, Util, RFB, */
 | 
			
		||||
    "use strict";
 | 
			
		||||
 | 
			
		||||
    // dirty fix for keyboard on iOS devices
 | 
			
		||||
    var keyboardVisible = false;
 | 
			
		||||
    var isTouchDevice = false;
 | 
			
		||||
    isTouchDevice = 'ontouchstart' in document.documentElement;
 | 
			
		||||
 | 
			
		||||
    // Load supporting scripts
 | 
			
		||||
    Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js",
 | 
			
		||||
        "input.js", "display.js", "jsunzip.js", "rfb.js"]);
 | 
			
		||||
 | 
			
		||||
    var rfb;
 | 
			
		||||
 | 
			
		||||
    function passwordRequired(rfb) {
 | 
			
		||||
        var msg;
 | 
			
		||||
        msg = '<form onsubmit="return setPassword();"';
 | 
			
		||||
        msg += 'role="form"';
 | 
			
		||||
        msg += '  style="margin-bottom: 0px">';
 | 
			
		||||
        msg += 'Password Required: ';
 | 
			
		||||
        msg += '<input type=password size=10 id="password_input" class="noVNC_status">';
 | 
			
		||||
        msg += '<\/form>';
 | 
			
		||||
        $D('noVNC_status_bar').setAttribute("class", "noVNC_status_warn");
 | 
			
		||||
        $D('noVNC_status').innerHTML = msg;
 | 
			
		||||
    }
 | 
			
		||||
    function setPassword() {
 | 
			
		||||
        rfb.sendPassword($D('password_input').value);
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    function sendCtrlAltDel() {
 | 
			
		||||
        rfb.sendCtrlAltDel();
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // dirty fix for keyboard on iOS devices
 | 
			
		||||
    function showKeyboard() {
 | 
			
		||||
        var kbi, skb, l;
 | 
			
		||||
        kbi = $D('keyboardinput');
 | 
			
		||||
        skb = $D('showKeyboard');
 | 
			
		||||
        l = kbi.value.length;
 | 
			
		||||
        if (keyboardVisible === false) {
 | 
			
		||||
            kbi.focus();
 | 
			
		||||
            try {
 | 
			
		||||
                kbi.setSelectionRange(l, l);
 | 
			
		||||
            } // Move the caret to the end
 | 
			
		||||
            catch (err) {
 | 
			
		||||
            } // setSelectionRange is undefined in Google Chrome
 | 
			
		||||
            keyboardVisible = true;
 | 
			
		||||
            //skb.className = "noVNC_status_button_selected";
 | 
			
		||||
        } else if (keyboardVisible === true) {
 | 
			
		||||
            kbi.blur();
 | 
			
		||||
            //skb.className = "noVNC_status_button";
 | 
			
		||||
            keyboardVisible = false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function updateState(rfb, state, oldstate, msg) {
 | 
			
		||||
        var s, sb, cad, level;
 | 
			
		||||
        s = $D('noVNC_status');
 | 
			
		||||
        sb = $D('noVNC_status_bar');
 | 
			
		||||
        cad = $D('sendCtrlAltDelButton');
 | 
			
		||||
        switch (state) {
 | 
			
		||||
            case 'failed':
 | 
			
		||||
                level = "error";
 | 
			
		||||
                break;
 | 
			
		||||
            case 'fatal':
 | 
			
		||||
                level = "error";
 | 
			
		||||
                break;
 | 
			
		||||
            case 'normal':
 | 
			
		||||
                level = "normal";
 | 
			
		||||
                break;
 | 
			
		||||
            case 'disconnected':
 | 
			
		||||
                level = "normal";
 | 
			
		||||
                break;
 | 
			
		||||
            case 'loaded':
 | 
			
		||||
                level = "normal";
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                level = "warn";
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (state === "normal") {
 | 
			
		||||
            cad.disabled = false;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            cad.disabled = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (typeof(msg) !== 'undefined') {
 | 
			
		||||
            sb.setAttribute("class", "noVNC_status_" + level);
 | 
			
		||||
            s.innerHTML = msg;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    window.onscriptsload = function () {
 | 
			
		||||
        var host, port, password, path, token;
 | 
			
		||||
 | 
			
		||||
        $D('sendCtrlAltDelButton').style.display = "inline";
 | 
			
		||||
        $D('sendCtrlAltDelButton').onclick = sendCtrlAltDel;
 | 
			
		||||
 | 
			
		||||
        // dirty fix for keyboard on iOS devices
 | 
			
		||||
        if (isTouchDevice) {
 | 
			
		||||
            $D('showKeyboard').onclick = showKeyboard;
 | 
			
		||||
            // Remove the address bar
 | 
			
		||||
            setTimeout(function () {
 | 
			
		||||
                window.scrollTo(0, 1);
 | 
			
		||||
            }, 100);
 | 
			
		||||
        } else {
 | 
			
		||||
            $D('showKeyboard').style.display = "none";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        WebUtil.init_logging(WebUtil.getQueryVar('logging', 'warn'));
 | 
			
		||||
        document.title = unescape(WebUtil.getQueryVar('title', 'noVNC'));
 | 
			
		||||
        // By default, use the host and port of server that served this file
 | 
			
		||||
        host = '{{ ws_host }}';
 | 
			
		||||
        port = '{{ ws_port }}';
 | 
			
		||||
        password = '{{ console_passwd }}';
 | 
			
		||||
 | 
			
		||||
        if ((!host) || (!port)) {
 | 
			
		||||
            updateState('failed',
 | 
			
		||||
                    "Must specify host and port in URL");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        rfb = new RFB({'target': $D('noVNC_canvas'),
 | 
			
		||||
            'encrypt': WebUtil.getQueryVar('encrypt',
 | 
			
		||||
                    (window.location.protocol === "https:")),
 | 
			
		||||
            'repeaterID': WebUtil.getQueryVar('repeaterID', ''),
 | 
			
		||||
            'true_color': WebUtil.getQueryVar('true_color', true),
 | 
			
		||||
            'local_cursor': WebUtil.getQueryVar('cursor', true),
 | 
			
		||||
            'shared': WebUtil.getQueryVar('shared', true),
 | 
			
		||||
            'view_only': WebUtil.getQueryVar('view_only', false),
 | 
			
		||||
            'updateState': updateState,
 | 
			
		||||
            'onPasswordRequired': passwordRequired});
 | 
			
		||||
        rfb.connect(host, port, password, path);
 | 
			
		||||
    };
 | 
			
		||||
</script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
{% load static %}
 | 
			
		||||
<script src="{% static "js/jquery.min.js" %}"></script>
 | 
			
		||||
<script src="{% static "js/bootstrap.min.js" %}"></script>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
{% load static %}
 | 
			
		||||
{% extends "base.html" %}
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
{% include 'header.html' %}
 | 
			
		||||
<body>
 | 
			
		||||
{% block title %}{% trans "Instances" %}{% endblock %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
<div class="container-fluid">
 | 
			
		||||
    <div class="row">
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -100,8 +100,8 @@
 | 
			
		|||
                    </tbody>
 | 
			
		||||
                </table>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
{% include 'footer.html' %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,11 +1,6 @@
 | 
			
		|||
"""
 | 
			
		||||
Django settings for webvirtcloud project.
 | 
			
		||||
 | 
			
		||||
For more information on this file, see
 | 
			
		||||
https://docs.djangoproject.com/en/1.7/topics/settings/
 | 
			
		||||
 | 
			
		||||
For the full list of settings and their values, see
 | 
			
		||||
https://docs.djangoproject.com/en/1.7/ref/settings/
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
| 
						 | 
				
			
			@ -71,3 +66,9 @@ STATICFILES_DIRS = (
 | 
			
		|||
TEMPLATE_DIRS = (
 | 
			
		||||
    os.path.join(BASE_DIR,  'templates'),
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# WebVirtCloud settings
 | 
			
		||||
WS_PORT = 6080
 | 
			
		||||
WS_HOST = '0.0.0.0'
 | 
			
		||||
WS_PUBLIC_HOST = None
 | 
			
		||||
WS_CERT = None
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue