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 '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() + '#istaceshapshosts') 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() + '#instancemedia') 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() + '#instancemedia') 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() + '#istaceshapshosts') 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() + '#instancesettings') 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() + '#instancesettings') if 'resize' in request.POST: msg = _("Resize") addlogmsg(request.user.id, instance.id, msg) 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.resize(cur_memory, memory, cur_vcpu, vcpu) return HttpResponseRedirect(request.get_full_path() + '#instancesettings') 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() + '#instancexml') 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() + '#console_pass') 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() + '#console_keymap') 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() + '#console_type') 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_graph(request, compute_id, vname): """ Return instance usage """ if not request.user.is_authenticated(): return HttpResponseRedirect(reverse('login')) datasets = {} datasets_rd = [] datasets_wr = [] json_blk = [] cookie_blk = {} blk_error = False datasets_rx = [] datasets_tx = [] json_net = [] cookie_net = {} net_error = False networks = None disks = None points = 5 curent_time = time.strftime("%H:%M:%S") compute = Compute.objects.get(id=compute_id) try: conn = wvmInstance(compute.hostname, compute.login, compute.password, compute.type, vname) status = conn.get_status() cpu_usage = conn.cpu_usage() blk_usage = conn.disk_usage() net_usage = conn.net_usage() conn.close() except libvirtError: status = None blk_usage = None cpu_usage = None net_usage = None if status == 1: cookies = request.COOKIES 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'])) if len(datasets['timer']) > points: datasets['timer'].pop(0) if len(datasets['cpu']) > points: datasets['cpu'].pop(0) 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')) try: datasets_rd = datasets['blk'][blk['dev']][0] datasets_wr = datasets['blk'][blk['dev']][1] except: blk_error = True if not blk_error: datasets_rd.append(int(blk['rd']) / 1048576) datasets_wr.append(int(blk['wr']) / 1048576) if len(datasets_rd) > points: datasets_rd.pop(0) if len(datasets_wr) >= points + 1: datasets_wr.pop(0) 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')) try: datasets_rx = datasets['net'][net['dev']][0] datasets_tx = datasets['net'][net['dev']][1] except: net_error = True if not net_error: datasets_rx.append(int(net['rx']) / 1048576) datasets_tx.append(int(net['tx']) / 1048576) if len(datasets_rx) > points: datasets_rx.pop(0) if len(datasets_tx) > points: datasets_tx.pop(0) json_net.append({'dev': net['dev'], 'data': [datasets_rx, datasets_tx]}) cookie_net[net['dev']] = [datasets_rx, datasets_tx] data = json.dumps({'status': status, 'cpudata': datasets['cpu'], 'blkdata': json_blk, 'netdata': json_net, 'timeline': datasets['timer']}) response = HttpResponse() response['Content-Type'] = "text/javascript" if status == 1: response.cookies['cpu'] = datasets['cpu'] response.cookies['timer'] = datasets['timer'] response.cookies['blk'] = cookie_blk response.cookies['net'] = cookie_net response.write(data) return response