1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2024-12-24 23:25:24 +00:00

Added sceleton for instancr page

This commit is contained in:
Retspen 2015-03-12 16:15:36 +02:00
parent e9236f22a2
commit e1ce8b53ac
4 changed files with 548 additions and 14 deletions

View file

@ -1,13 +1,18 @@
from string import letters, digits
from random import choice
from bisect import insort
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.shortcuts import render from django.shortcuts import render
from django.utils.translation import ugettext_lazy as _
from computes.models import Compute from computes.models import Compute
from instances.models import Instance from instances.models import Instance
from users.models import UserInstance from users.models import UserInstance
from vrtManager.hostdetails import wvmHostDetails from vrtManager.hostdetails import wvmHostDetails
from vrtManager.instance import wvmInstance, wvmInstances from vrtManager.instance import wvmInstance, wvmInstances
from vrtManager.connection import connection_manager from vrtManager.connection import connection_manager
from libvirt import libvirtError from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE
from webvirtcloud.settings import QEMU_KEYMAPS, QEMU_CONSOLE_TYPES
def index(request): def index(request):
@ -92,7 +97,7 @@ def instances(request):
return render(request, 'instances.html', locals()) return render(request, 'instances.html', locals())
def instance(request, comptes_id, vname): def instance(request, compute_id, vname):
""" """
:param request: :param request:
:return: :return:
@ -101,4 +106,220 @@ def instance(request, comptes_id, vname):
if not request.user.is_authenticated(): if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('index')) return HttpResponseRedirect(reverse('index'))
def show_clone_disk(disks):
clone_disk = []
for disk in disks:
if disk['image'] is None:
continue
if disk['image'].count(".") and len(disk['image'].rsplit(".", 1)[1]) <= 7:
name, suffix = disk['image'].rsplit(".", 1)
image = name + "-clone" + "." + suffix
else:
image = disk['image'] + "-clone"
clone_disk.append(
{'dev': disk['dev'], 'storage': disk['storage'], 'image': image, 'format': disk['format']})
return clone_disk
errors = []
messages = []
compute = Compute.objects.get(id=compute_id)
computes = Compute.objects.all()
computes_count = len(computes)
keymaps = QEMU_KEYMAPS
console_types = QEMU_CONSOLE_TYPES
try:
conn = wvmInstance(compute.hostname,
compute.login,
compute.password,
compute.type,
vname)
status = conn.get_status()
autostart = conn.get_autostart()
vcpu = conn.get_vcpu()
cur_vcpu = conn.get_cur_vcpu()
uuid = conn.get_uuid()
memory = conn.get_memory()
cur_memory = conn.get_cur_memory()
description = conn.get_description()
disks = conn.get_disk_device()
media = conn.get_media_device()
networks = conn.get_net_device()
media_iso = sorted(conn.get_iso_media())
vcpu_range = conn.get_max_cpus()
memory_range = [256, 512, 768, 1024, 2048, 4096, 6144, 8192, 16384]
if memory not in memory_range:
insort(memory_range, memory)
if cur_memory not in memory_range:
insort(memory_range, cur_memory)
memory_host = conn.get_max_memory()
vcpu_host = len(vcpu_range)
telnet_port = conn.get_telnet_port()
console_type = conn.get_console_type()
console_port = conn.get_console_port()
console_keymap = conn.get_console_keymap()
snapshots = sorted(conn.get_snapshot(), reverse=True)
inst_xml = conn._XMLDesc(VIR_DOMAIN_XML_SECURE)
has_managed_save_image = conn.get_managed_save_image()
clone_disks = show_clone_disk(disks)
console_passwd = conn.get_console_passwd()
except libvirtError as err:
errors.append(err)
try:
instance = Instance.objects.get(compute_id=compute_id, name=vname)
if instance.uuid != uuid:
instance.uuid = uuid
instance.save()
except Instance.DoesNotExist:
instance = Instance(compute_id=compute_id, name=vname, uuid=uuid)
instance.save()
try:
if request.method == 'POST':
if 'start' in request.POST:
conn.start()
return HttpResponseRedirect(request.get_full_path() + '#shutdown')
if 'power' in request.POST:
if 'shutdown' == request.POST.get('power', ''):
conn.shutdown()
return HttpResponseRedirect(request.get_full_path() + '#shutdown')
if 'destroy' == request.POST.get('power', ''):
conn.force_shutdown()
return HttpResponseRedirect(request.get_full_path() + '#forceshutdown')
if 'managedsave' == request.POST.get('power', ''):
conn.managedsave()
return HttpResponseRedirect(request.get_full_path() + '#managedsave')
if 'deletesaveimage' in request.POST:
conn.managed_save_remove()
return HttpResponseRedirect(request.get_full_path() + '#managedsave')
if 'suspend' in request.POST:
conn.suspend()
return HttpResponseRedirect(request.get_full_path() + '#suspend')
if 'resume' in request.POST:
conn.resume()
return HttpResponseRedirect(request.get_full_path() + '#suspend')
if 'delete' in request.POST:
if conn.get_status() == 1:
conn.force_shutdown()
try:
instance = Instance.objects.get(compute_id=host_id, name=vname)
instance.delete()
if request.POST.get('delete_disk', ''):
conn.delete_disk()
finally:
conn.delete()
return HttpResponseRedirect(reverse('instances', args=[host_id]))
if 'snapshot' in request.POST:
name = request.POST.get('name', '')
conn.create_snapshot(name)
return HttpResponseRedirect(request.get_full_path() + '#istaceshapshosts')
if 'umount_iso' in request.POST:
image = request.POST.get('path', '')
dev = request.POST.get('umount_iso', '')
conn.umount_iso(dev, image)
return HttpResponseRedirect(request.get_full_path() + '#instancemedia')
if 'mount_iso' in request.POST:
image = request.POST.get('media', '')
dev = request.POST.get('mount_iso', '')
conn.mount_iso(dev, image)
return HttpResponseRedirect(request.get_full_path() + '#instancemedia')
if 'set_autostart' in request.POST:
conn.set_autostart(1)
return HttpResponseRedirect(request.get_full_path() + '#instancesettings')
if 'unset_autostart' in request.POST:
conn.set_autostart(0)
return HttpResponseRedirect(request.get_full_path() + '#instancesettings')
if 'change_settings' in request.POST:
description = request.POST.get('description', '')
vcpu = request.POST.get('vcpu', '')
cur_vcpu = request.POST.get('cur_vcpu', '')
memory = request.POST.get('memory', '')
memory_custom = request.POST.get('memory_custom', '')
if memory_custom:
memory = memory_custom
cur_memory = request.POST.get('cur_memory', '')
cur_memory_custom = request.POST.get('cur_memory_custom', '')
if cur_memory_custom:
cur_memory = cur_memory_custom
conn.change_settings(description, cur_memory, memory, cur_vcpu, vcpu)
return HttpResponseRedirect(request.get_full_path() + '#instancesettings')
if 'change_xml' in request.POST:
xml = request.POST.get('inst_xml', '')
if xml:
conn._defineXML(xml)
return HttpResponseRedirect(request.get_full_path() + '#instancexml')
if 'set_console_passwd' in request.POST:
if request.POST.get('auto_pass', ''):
passwd = ''.join([choice(letters + digits) for i in xrange(12)])
else:
passwd = request.POST.get('console_passwd', '')
clear = request.POST.get('clear_pass', False)
if clear:
passwd = ''
if not passwd and not clear:
msg = _("Enter the console password or select Generate")
errors.append(msg)
if not errors:
if not conn.set_console_passwd(passwd):
msg = _("Error setting console password. You should check that your instance have an graphic device.")
errors.append(msg)
else:
return HttpResponseRedirect(request.get_full_path() + '#console_pass')
if 'set_console_keymap' in request.POST:
keymap = request.POST.get('console_keymap', '')
clear = request.POST.get('clear_keymap', False)
if clear:
conn.set_console_keymap('')
else:
conn.set_console_keymap(keymap)
return HttpResponseRedirect(request.get_full_path() + '#console_keymap')
if 'set_console_type' in request.POST:
console_type = request.POST.get('console_type', '')
conn.set_console_type(console_type)
return HttpResponseRedirect(request.get_full_path() + '#console_type')
if 'migrate' in request.POST:
compute_id = request.POST.get('compute_id', '')
live = request.POST.get('live_migrate', False)
unsafe = request.POST.get('unsafe_migrate', False)
xml_del = request.POST.get('xml_delete', False)
new_compute = Compute.objects.get(id=compute_id)
conn_migrate = wvmInstances(new_compute.hostname,
new_compute.login,
new_compute.password,
new_compute.type)
conn_migrate.moveto(conn, vname, live, unsafe, xml_del)
conn_migrate.define_move(vname)
conn_migrate.close()
return HttpResponseRedirect(reverse('instance', args=[compute_id, vname]))
if 'delete_snapshot' in request.POST:
snap_name = request.POST.get('name', '')
conn.snapshot_delete(snap_name)
return HttpResponseRedirect(request.get_full_path() + '#istaceshapshosts')
if 'revert_snapshot' in request.POST:
snap_name = request.POST.get('name', '')
conn.snapshot_revert(snap_name)
msg = _("Successful revert snapshot: ")
msg += snap_name
messages.append(msg)
if 'clone' in request.POST:
clone_data = {}
clone_data['name'] = request.POST.get('name', '')
for post in request.POST:
if 'disk' or 'meta' in post:
clone_data[post] = request.POST.get(post, '')
conn.clone_instance(clone_data)
return HttpResponseRedirect(reverse('instance', args=[host_id, clone_data['name']]))
conn.close()
except libvirtError as err:
errors.append(err)
return render(request, 'instance.html', locals()) return render(request, 'instance.html', locals())

View file

@ -87,3 +87,54 @@ body {
.btn-header { .btn-header {
margin-top: 5px; margin-top: 5px;
} }
#action-block {
display: block;
padding: 15px 0;
font-weight: 400;
font-size: 14px;
width: 65px;
}
#action-button {
text-align: center;
}
.tab-pane-bordered {
border: 1px solid #eee;
border-top-width: 0;
padding: 20px;
}
p {
display: block;
margin: 10px 10px 10px 10px;
}
#power {
margin-top: 20px;
}
#access {
margin-top: 20px;
}
#resize {
margin-top: 20px;
}
#snapshots {
margin-top: 20px;
}
#settings {
margin-top: 20px;
}
#graphics {
margin-top: 20px;
}
#undefine {
margin-top: 20px;
}

View file

@ -2,20 +2,275 @@
{% load i18n %} {% load i18n %}
{% block title %}{% trans "Instance" %} - {{ vname }}{% endblock %} {% block title %}{% trans "Instance" %} - {{ vname }}{% endblock %}
{% block content %} {% block content %}
<div class="container-fluid"> <!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12">
{% include 'sidebar.html' %}
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
{% include 'create_inst_block.html' %}
<h1 class="page-header">{{ vname }}</h1> <h1 class="page-header">{{ vname }}</h1>
</div>
</div>
<!-- /.row -->
{% include 'errors_block.html' %} {% include 'errors_block.html' %}
<div class="row">
<div class="col-lg-12">
Status:
{% ifequal status 5 %}
<span class="text-danger">{% trans "Off" %}</span>
{% endifequal %}
{% ifequal status 1 %}
<span class="text-success">{% trans "Active" %}</span>
{% endifequal %}
{% ifequal status 3 %}
<span class="text-warning">{% trans "Suspend" %}</span>
{% endifequal %}
Vcpu: {% if cur_vcpu %}{{ cur_vcpu }}{% else %}{{ vcpu }}{% endif %}
Ram: {{ cur_memory }}{% trans "MB" %}
{% ifnotequal description 'None' %}
{{ description }}
{% endifnotequal %}
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div role="tabpanel">
<!-- Nav tabs -->
<ul class="nav nav-pills" role="tablist">
<li role="presentation" class="active">
<a href="#power" id="action-button" aria-controls="power" role="tab" data-toggle="tab">
<span id="action-block" class="glyphicon glyphicon-off" aria-hidden="true"></span>
{% trans "Power" %}
</a>
</li>
<li role="presentation">
<a href="#access" id="action-button" aria-controls="access" role="tab" data-toggle="tab">
<span id="action-block" class="glyphicon glyphicon-lock" aria-hidden="true"></span>
{% trans "Access" %}
</a>
</li>
<li role="presentation">
<a href="#resize" id="action-button" aria-controls="resize" role="tab" data-toggle="tab">
<span id="action-block" class="glyphicon glyphicon-resize-full" aria-hidden="true"></span>
{% trans "Resize" %}
</a>
</li>
<li role="presentation">
<a href="#snapshots" id="action-button" aria-controls="snapshots" role="tab" data-toggle="tab">
<span id="action-block" class="glyphicon glyphicon-camera" aria-hidden="true"></span>
{% trans "Snapshots" %}
</a>
</li>
<li role="presentation">
<a href="#settings" id="action-button" aria-controls="settings" role="tab" data-toggle="tab">
<span id="action-block" class="glyphicon glyphicon-cog" aria-hidden="true"></span>
{% trans "Settings" %}
</a>
</li>
<li role="presentation">
<a href="#graphics" id="action-button" aria-controls="graphics" role="tab" data-toggle="tab">
<span id="action-block" class="glyphicon glyphicon-signal" aria-hidden="true"></span>
{% trans "Graphs" %}
</a>
</li>
<li role="presentation">
<a href="#undefine" id="action-button" aria-controls="undefine" role="tab" data-toggle="tab">
<span id="action-block" class="glyphicon glyphicon-trash" aria-hidden="true"></span>
{% trans "Destroy" %}
</a>
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="power">
<div role="tabpanel">
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
{% ifequal status 1 %}
<li role="presentation" class="active">
<a href="#reboot" aria-controls="reboot" role="tab" data-toggle="tab">
{% trans "Reboot" %}
</a>
</li>
<li role="presentation">
<a href="#poweroff" aria-controls="poweroff" role="tab" data-toggle="tab">
{% trans "Power Off" %}
</a>
</li>
<li role="presentation">
<a href="#suspend" aria-controls="suspend" role="tab" data-toggle="tab">
{% trans "Suspend" %}
</a>
</li>
{% endifequal %}
{% ifequal status 3 %}
<li role="presentation" class="active">
<a href="#resume" aria-controls="resume" role="tab" data-toggle="tab">
{% trans "Reboot" %}
</a>
</li>
{% endifequal %}
{% ifequal status 5 %}
<li role="presentation" class="active">
<a href="#boot" aria-controls="boot" role="tab" data-toggle="tab">
{% trans "Boot" %}
</a>
</li>
{% endifequal %}
</ul>
<!-- Tab panes -->
<div class="tab-content">
{% ifequal status 1 %}
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="reboot">
<p>Reboot</p>
</div>
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="poweroff">
<p>Power Off</p>
</div>
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="suspend">
<p>Suspend</p>
</div>
{% endifequal %}
{% ifequal status 3 %}
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="resume">
<p>Resume</p>
</div>
{% endifequal %}
{% ifequal status 5 %}
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="boot">
<p>Boot</p>
</div>
{% endifequal %}
</div>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="access">
<div role="tabpanel">
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">
<a href="#vnconsole" aria-controls="vnconsole" role="tab" data-toggle="tab">
{% trans "Console" %}
</a>
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="vnconsole">
<p>Console</p>
</div>
</div>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="resize">
<div role="tabpanel">
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">
<a href="#resizevm" aria-controls="resizevm" role="tab" data-toggle="tab">
{% trans "Resize Instance" %}
</a>
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="resizevm">
<p>Resize Instance</p>
</div>
</div>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="snapshots">
<div role="tabpanel">
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">
<a href="#takesnapshot" aria-controls="takesnapshot" role="tab" data-toggle="tab">
{% trans "Take Snapshot" %}
</a>
</li>
<li role="presentation">
<a href="#restoresnapshot" aria-controls="restoresnapshot" role="tab" data-toggle="tab">
{% trans "Restore From Snaphot" %}
</a>
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="takesnapshot">
<p>Take Snapshots</p>
</div>
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="restoresnapshot">
<p>Restore Snapshots</p>
</div>
</div>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="settings">
<div role="tabpanel">
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">
<a href="#autostart" aria-controls="autostart" role="tab" data-toggle="tab">
{% trans "Autostart" %}
</a>
</li>
<li role="presentation">
<a href="#media" aria-controls="media" role="tab" data-toggle="tab">
{% trans "Media" %}
</a>
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="autostart">
<p>Autostart</p>
</div>
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="media">
<p>Cdrome</p>
</div>
</div>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="graphics">
<div role="tabpanel">
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">
<a href="#graps" aria-controls="graps" role="tab" data-toggle="tab">
{% trans "Real Time" %}
</a>
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="graps">
<p>Graphics</p>
</div>
</div>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="undefine">
<div role="tabpanel">
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">
<a href="#destroy" aria-controls="destroy" role="tab" data-toggle="tab">
{% trans "Destroy Instance" %}
</a>
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="destroy">
<p>Destroy Instance</p>
</div>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -89,6 +89,13 @@ QEMU_CONSOLE_TYPES = ['vnc', 'spice']
# default console type # default console type
QEMU_CONSOLE_DEFAULT_TYPE = 'vnc' QEMU_CONSOLE_DEFAULT_TYPE = 'vnc'
# list taken from http://qemu.weilnetz.de/qemu-doc.html#sec_005finvocation
QEMU_KEYMAPS = ['ar', 'da', 'de', 'de-ch', 'en-gb', 'en-us', 'es', 'et', 'fi',
'fo', 'fr', 'fr-be', 'fr-ca', 'fr-ch', 'hr', 'hu', 'is', 'it',
'ja', 'lt', 'lv', 'mk', 'nl', 'nl-be', 'no', 'pl', 'pt',
'pt-br', 'ru', 'sl', 'sv', 'th', 'tr']
# keepalive interval and count for libvirt connections # keepalive interval and count for libvirt connections
LIBVIRT_KEEPALIVE_INTERVAL = 5 LIBVIRT_KEEPALIVE_INTERVAL = 5
LIBVIRT_KEEPALIVE_COUNT = 5 LIBVIRT_KEEPALIVE_COUNT = 5