1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2024-12-24 15:15:22 +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.core.urlresolvers import reverse
from django.shortcuts import render
from django.utils.translation import ugettext_lazy as _
from computes.models import Compute
from instances.models import Instance
from users.models import UserInstance
from vrtManager.hostdetails import wvmHostDetails
from vrtManager.instance import wvmInstance, wvmInstances
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):
@ -92,7 +97,7 @@ def instances(request):
return render(request, 'instances.html', locals())
def instance(request, comptes_id, vname):
def instance(request, compute_id, vname):
"""
:param request:
:return:
@ -101,4 +106,220 @@ def instance(request, comptes_id, vname):
if not request.user.is_authenticated():
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())

View file

@ -87,3 +87,54 @@ body {
.btn-header {
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,21 +2,276 @@
{% load i18n %}
{% block title %}{% trans "Instance" %} - {{ vname }}{% endblock %}
{% block content %}
<div class="container-fluid">
<!-- Page Heading -->
<div class="row">
{% 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' %}
<div class="col-lg-12">
<h1 class="page-header">{{ vname }}</h1>
</div>
</div>
<!-- /.row -->
{% 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>
<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>
{% endblock %}

View file

@ -89,6 +89,13 @@ QEMU_CONSOLE_TYPES = ['vnc', 'spice']
# default console type
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
LIBVIRT_KEEPALIVE_INTERVAL = 5
LIBVIRT_KEEPALIVE_COUNT = 5