import time import json from string import letters, digits from random import choice from bisect import insort from django.http import HttpResponse, 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 accounts.models import UserInstance from vrtManager.hostdetails import wvmHostDetails from vrtManager.instance import wvmInstance, wvmInstances from vrtManager.connection import connection_manager from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE from webvirtcloud.settings import QEMU_KEYMAPS, QEMU_CONSOLE_TYPES from logs.views import addlogmsg def index(request): """ :param request: :return: """ if not request.user.is_authenticated(): return HttpResponseRedirect(reverse('login')) else: return HttpResponseRedirect(reverse('instances')) def instances(request): """ :param request: :return: """ if not request.user.is_authenticated(): return HttpResponseRedirect(reverse('index')) error_messages = [] all_host_vms = {} all_user_vms = {} computes = Compute.objects.all() if not request.user.is_superuser: user_instances = UserInstance.objects.all() for usr_inst in user_instances: if connection_manager.host_is_up(usr_inst.instance.compute.type, usr_inst.instance.compute.hostname): conn = wvmHostDetails(usr_inst.instance.compute, usr_inst.instance.compute.login, usr_inst.instance.compute.password, usr_inst.instance.compute.type) all_user_vms[usr_inst] = conn.get_user_instances(usr_inst.instance.name) all_user_vms[usr_inst].update({'compute_id': usr_inst.instance.compute.id}) else: for comp in computes: if connection_manager.host_is_up(comp.type, comp.hostname): try: conn = wvmHostDetails(comp, comp.login, comp.password, comp.type) all_host_vms[comp.id, comp.name] = conn.get_host_instances() for vm, info in conn.get_host_instances().items(): try: check_uuid = Instance.objects.get(compute_id=comp.id, name=vm) if check_uuid.uuid != info['uuid']: check_uuid.save() except Instance.DoesNotExist: check_uuid = Instance(compute_id=comp.id, name=vm, uuid=info['uuid']) check_uuid.save() conn.close() except libvirtError as lib_err: error_messages.append(lib_err) if request.method == 'POST': name = request.POST.get('name', '') compute_id = request.POST.get('compute_id', '') instance = Instance.objects.get(compute_id=compute_id, name=name) try: conn = wvmInstances(instance.compute.hostname, instance.compute.login, instance.compute.password, instance.compute.type) if 'poweron' in request.POST: msg = _("Power On") addlogmsg(request.user.id, instance.id, msg) conn.start(name) return HttpResponseRedirect(request.get_full_path()) if 'powercycle' in request.POST: msg = _("Power Cycle") conn.force_shutdown(name) conn.start() addlogmsg(request.user.id, instance.id, msg) return HttpResponseRedirect(request.get_full_path()) if 'poweroff' in request.POST: msg = _("Power Off") addlogmsg(request.user.id, instance.id, msg) conn.shutdown(name) return HttpResponseRedirect(request.get_full_path()) if request.user.is_superuser: if 'suspend' in request.POST: msg = _("Suspend") addlogmsg(request.user.id, instance.id, msg) conn.suspend(name) return HttpResponseRedirect(request.get_full_path()) if 'resume' in request.POST: msg = _("Resume") addlogmsg(request.user.id, instance.id, msg) conn.resume(name) return HttpResponseRedirect(request.get_full_path()) except libvirtError as lib_err: error_messages.append(lib_err) addlogmsg(request.user.id, instance.id, lib_err.message) return render(request, 'instances.html', locals()) def instance(request, compute_id, vname): """ :param request: :return: """ if not request.user.is_authenticated(): return HttpResponseRedirect(reverse('index')) error_messages = [] 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: userinstace = UserInstance.objects.get(instance__compute_id=compute_id, instance__name=vname, user__id=request.user.id) except UserInstance.DoesNotExist: userinstace = None if not request.user.is_superuser: if not userinstace: 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 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() 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() if request.method == 'POST': if 'poweron' in request.POST: msg = _("Power On") addlogmsg(request.user.id, instance.id, msg) conn.start() return HttpResponseRedirect(request.get_full_path() + '#poweron') if 'powercycle' in request.POST: msg = _("Power Cycle") addlogmsg(request.user.id, instance.id, msg) conn.force_shutdown() conn.start() return HttpResponseRedirect(request.get_full_path() + '#powercycle') if 'poweroff' == request.POST.get('power', ''): msg = _("Power Off") addlogmsg(request.user.id, instance.id, msg) conn.shutdown() return HttpResponseRedirect(request.get_full_path() + '#poweroff') if 'delete' in request.POST: msg = _("Destroy") addlogmsg(request.user.id, instance.id, msg) if conn.get_status() == 1: conn.force_shutdown() try: instance = Instance.objects.get(compute_id=compute_id, name=vname) instance.delete() if request.POST.get('delete_disk', ''): conn.delete_disk() finally: if not request.user.is_superuser: del_userinstance = UserInstance.objects.get(id=userinstace.id) del_userinstance.delete() else: try: del_userinstance = UserInstance.objects.filter(instance__compute_id=compute_id, instance__name=vname) del_userinstance.save() except UserInstance.DoesNotExist: pass conn.delete() return HttpResponseRedirect(reverse('instances')) if 'resize' in request.POST: msg = _("Resize") addlogmsg(request.user.id, instance.id, msg) 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.resize(cur_memory, memory, cur_vcpu, vcpu) return HttpResponseRedirect(request.get_full_path() + '#resize') if 'umount_iso' in request.POST: msg = _("Mount media") addlogmsg(request.user.id, instance.id, msg) image = request.POST.get('path', '') dev = request.POST.get('umount_iso', '') conn.umount_iso(dev, image) return HttpResponseRedirect(request.get_full_path() + '#media') if 'mount_iso' in request.POST: msg = _("Umount media") addlogmsg(request.user.id, instance.id, msg) image = request.POST.get('media', '') dev = request.POST.get('mount_iso', '') conn.mount_iso(dev, image) return HttpResponseRedirect(request.get_full_path() + '#media') if 'snapshot' in request.POST: msg = _("New snapshot") addlogmsg(request.user.id, instance.id, msg) name = request.POST.get('name', '') conn.create_snapshot(name) return HttpResponseRedirect(request.get_full_path() + '#snapshot') if 'delete_snapshot' in request.POST: msg = _("Delete snapshot") addlogmsg(request.user.id, instance.id, msg) snap_name = request.POST.get('name', '') conn.snapshot_delete(snap_name) return HttpResponseRedirect(request.get_full_path() + '#snapshot') if 'revert_snapshot' in request.POST: msg = _("Revert snapshot") addlogmsg(request.user.id, instance.id, msg) snap_name = request.POST.get('name', '') conn.snapshot_revert(snap_name) msg = _("Successful revert snapshot: ") msg += snap_name messages.append(msg) if request.user.is_superuser: if 'suspend' in request.POST: msg = _("Suspend") addlogmsg(request.user.id, instance.id, msg) conn.suspend() return HttpResponseRedirect(request.get_full_path() + '#resume') if 'resume' in request.POST: msg = _("Resume") addlogmsg(request.user.id, instance.id, msg) conn.resume() return HttpResponseRedirect(request.get_full_path() + '#suspend') if 'set_autostart' in request.POST: msg = _("Set autostart") addlogmsg(request.user.id, instance.id, msg) conn.set_autostart(1) return HttpResponseRedirect(request.get_full_path() + '#autostart') if 'unset_autostart' in request.POST: msg = _("Unset autostart") addlogmsg(request.user.id, instance.id, msg) conn.set_autostart(0) return HttpResponseRedirect(request.get_full_path() + '#autostart') if 'change_xml' in request.POST: msg = _("Edit XML") addlogmsg(request.user.id, instance.id, msg) exit_xml = request.POST.get('inst_xml', '') if exit_xml: conn._defineXML(exit_xml) return HttpResponseRedirect(request.get_full_path() + '#xmledit') if 'set_console_passwd' in request.POST: msg = _("Set VNC password") addlogmsg(request.user.id, instance.id, msg) 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") error_messages.append(msg) if not error_messages: if not conn.set_console_passwd(passwd): msg = _("Error setting console password. You should check that your instance have an graphic device.") error_messages.append(msg) else: return HttpResponseRedirect(request.get_full_path() + '#vncedit') if 'set_console_keymap' in request.POST: msg = _("Set VNC keymap") addlogmsg(request.user.id, instance.id, msg) 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() + '#vncedit') if 'set_console_type' in request.POST: msg = _("Set VNC type") addlogmsg(request.user.id, instance.id, msg) console_type = request.POST.get('console_type', '') conn.set_console_type(console_type) return HttpResponseRedirect(request.get_full_path() + '#vncedit') if 'migrate' in request.POST: msg = _("Migrate") addlogmsg(request.user.id, instance.id, msg) 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 'clone' in request.POST: msg = _("Clone") addlogmsg(request.user.id, instance.id, msg) 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=[compute_id, clone_data['name']])) conn.close() except libvirtError as lib_err: error_messages.append(lib_err.message) addlogmsg(request.user.id, instance.id, lib_err.message) return render(request, 'instance.html', locals()) def inst_status(request, compute_id, vname): """ :param request: :return: """ if not request.user.is_authenticated(): return HttpResponseRedirect(reverse('login')) compute = Compute.objects.get(id=compute_id) try: conn = wvmInstance(compute.hostname, compute.login, compute.password, compute.type, vname) status = conn.get_status() conn.close() except libvirtError: status = None data = json.dumps({'status': status}) response = HttpResponse() response['Content-Type'] = "text/javascript" response.write(data) return response def inst_graph(request, compute_id, vname): """ :param request: :return: """ if not request.user.is_authenticated(): return HttpResponseRedirect(reverse('login')) datasets = {} datasets_rd = [] datasets_wr = [] json_blk = [] cookie_blk = {} datasets_rx = [] datasets_tx = [] json_net = [] cookie_net = {} points = 5 curent_time = time.strftime("%H:%M:%S") compute = Compute.objects.get(id=compute_id) cookies = request.COOKIES response = HttpResponse() response['Content-Type'] = "text/javascript" def check_points(dataset): if len(dataset) > points: dataset.pop(0) return dataset try: conn = wvmInstance(compute.hostname, compute.login, compute.password, compute.type, vname) cpu_usage = conn.cpu_usage() blk_usage = conn.disk_usage() net_usage = conn.net_usage() conn.close() if cookies.get('cpu') == '{}' or not cookies.get('cpu') or not cpu_usage: datasets['cpu'] = [0] datasets['timer'] = [curent_time] else: datasets['cpu'] = eval(cookies.get('cpu')) datasets['timer'] = eval(cookies.get('timer')) datasets['timer'].append(curent_time) datasets['cpu'].append(int(cpu_usage['cpu'])) datasets['timer'] = check_points(datasets['timer']) datasets['cpu'] = check_points(datasets['cpu']) for blk in blk_usage: if cookies.get('blk') == '{}' or not cookies.get('blk') or not blk_usage: datasets_wr.append(0) datasets_rd.append(0) else: datasets['blk'] = eval(cookies.get('blk')) datasets_rd = datasets['blk'][blk['dev']][0] datasets_wr = datasets['blk'][blk['dev']][1] datasets_rd.append(int(blk['rd']) / 1048576) datasets_wr.append(int(blk['wr']) / 1048576) datasets_rd = check_points(datasets_rd) datasets_wr = check_points(datasets_wr) json_blk.append({'dev': blk['dev'], 'data': [datasets_rd, datasets_wr]}) cookie_blk[blk['dev']] = [datasets_rd, datasets_wr] for net in net_usage: if cookies.get('net') == '{}' or not cookies.get('net') or not net_usage: datasets_rx.append(0) datasets_tx.append(0) else: datasets['net'] = eval(cookies.get('net')) datasets_rx = datasets['net'][net['dev']][0] datasets_tx = datasets['net'][net['dev']][1] datasets_rx.append(int(net['rx']) / 1048576) datasets_tx.append(int(net['tx']) / 1048576) datasets_rx = check_points(datasets_rx) datasets_tx = check_points(datasets_tx) json_net.append({'dev': net['dev'], 'data': [datasets_rx, datasets_tx]}) cookie_net[net['dev']] = [datasets_rx, datasets_tx] data = json.dumps({'cpudata': datasets['cpu'], 'blkdata': json_blk, 'netdata': json_net, 'timeline': datasets['timer']}) response.cookies['cpu'] = datasets['cpu'] response.cookies['timer'] = datasets['timer'] response.cookies['blk'] = cookie_blk response.cookies['net'] = cookie_net except libvirtError: data = json.dumps({'error': 'Error 500'}) response.write(data) return response