Example #1
0
    def refresh_instance_database(comp, vm, info):
        instances = Instance.objects.filter(name=vm)
        if instances.count() > 1:
            for i in instances:
                user_instances_count = UserInstance.objects.filter(instance=i).count()
                if user_instances_count == 0:
                    addlogmsg(request.user.username, i.name, _("Deleting due to multiple records."))
                    i.delete()
        
        try:
            check_uuid = Instance.objects.get(compute_id=comp["id"], name=vm)
            if check_uuid.uuid != info['uuid']:
                check_uuid.save()

            all_host_vms[comp["id"],
                         comp["name"],
                         comp["status"],
                         comp["cpu"],
                         comp["mem_size"],
                         comp["mem_perc"]][vm]['is_template'] = check_uuid.is_template
            all_host_vms[comp["id"],
                         comp["name"],
                         comp["status"],
                         comp["cpu"],
                         comp["mem_size"],
                         comp["mem_perc"]][vm]['userinstances'] = get_userinstances_info(check_uuid)
        except Instance.DoesNotExist:
            check_uuid = Instance(compute_id=comp["id"], name=vm, uuid=info['uuid'])
            check_uuid.save()
Example #2
0
    def refresh_instance_database(comp, vm, info):
        instances = Instance.objects.filter(name=vm)
        if instances.count() > 1:
            for i in instances:
                user_instances_count = UserInstance.objects.filter(
                    instance=i).count()
                if user_instances_count == 0:
                    addlogmsg(request.user.username, i.name,
                              _("Deleting due to multiple records."))
                    i.delete()

        try:
            check_uuid = Instance.objects.get(compute_id=comp["id"], name=vm)
            if check_uuid.uuid != info['uuid']:
                check_uuid.save()

            all_host_vms[comp_info["id"], comp_info["name"],
                         comp_info["status"], comp_info["cpu"],
                         comp_info["mem_size"], comp_info["mem_perc"]][vm][
                             'is_template'] = check_uuid.is_template
            all_host_vms[comp_info["id"], comp_info["name"],
                         comp_info["status"], comp_info["cpu"],
                         comp_info["mem_size"], comp_info["mem_perc"]][vm][
                             'userinstances'] = get_userinstances_info(
                                 check_uuid)
        except Instance.DoesNotExist:
            check_uuid = Instance(compute_id=comp["id"],
                                  name=vm,
                                  uuid=info['uuid'])
            check_uuid.save()
Example #3
0
def refresh_instance_database(comp, inst_name, info, all_host_vms, user):
    # Multiple Instance Name Check
    instances = Instance.objects.filter(name=inst_name)
    if instances.count() > 1:
        for i in instances:
            user_instances_count = UserInstance.objects.filter(
                instance=i).count()
            if user_instances_count == 0:
                addlogmsg(
                    user.username, i.name,
                    _("Deleting due to multiple(Instance Name) records."))
                i.delete()

    # Multiple UUID Check
    instances = Instance.objects.filter(uuid=info['uuid'])
    if instances.count() > 1:
        for i in instances:
            if i.name != inst_name:
                addlogmsg(user.username, i.name,
                          _("Deleting due to multiple(UUID) records."))
                i.delete()

    try:
        inst_on_db = Instance.objects.get(compute_id=comp["id"],
                                          name=inst_name)
        if inst_on_db.uuid != info['uuid']:
            inst_on_db.save()

        all_host_vms[comp["id"], comp["name"], comp["status"], comp["cpu"],
                     comp["mem_size"], comp["mem_perc"]][inst_name][
                         'is_template'] = inst_on_db.is_template
        all_host_vms[comp["id"], comp["name"], comp["status"], comp["cpu"],
                     comp["mem_size"], comp["mem_perc"]][inst_name][
                         'userinstances'] = get_userinstances_info(inst_on_db)
    except Instance.DoesNotExist:
        inst_on_db = Instance(compute_id=comp["id"],
                              name=inst_name,
                              uuid=info['uuid'])
        inst_on_db.save()
Example #4
0
def nwfilters(request, compute_id):
    """
    :param request:
    :return:
    """

    if not request.user.is_superuser:
        return HttpResponseRedirect(reverse('index'))

    error_messages = []
    nwfilters_all = []
    compute = get_object_or_404(Compute, pk=compute_id)

    try:
        conn = wvmNWFilters(compute.hostname, compute.login, compute.password,
                            compute.type)

        if request.method == 'POST':
            if 'create_nwfilter' in request.POST:
                xml = request.POST.get('nwfilter_xml', '')
                if xml:
                    try:
                        util.etree.fromstring(xml)
                        name = util.get_xml_path(xml, '/filter/@name')
                        uuid = util.get_xml_path(xml, '/filter/uuid')
                    except util.etree.ParseError:
                        name = None

                    for nwf in nwfilters:
                        if name == nwf.name():
                            error_msg = _(
                                "A network filter with this name already exists"
                            )
                            raise Exception(error_msg)
                        if uuid == nwf.UUIDString():
                            error_msg = _(
                                "A network filter with this uuid already exists"
                            )
                            raise Exception(error_msg)
                    else:
                        try:
                            msg = _("Creating NWFilter: %s" % name)
                            conn.create_nwfilter(xml)
                            addlogmsg(request.user.username, compute.hostname,
                                      msg)
                        except libvirtError as lib_err:
                            error_messages.append(lib_err.message)
                            addlogmsg(request.user.username, compute.hostname,
                                      lib_err.message)

            if 'del_nwfilter' in request.POST:
                name = request.POST.get('nwfiltername', '')
                msg = _("Deleting NWFilter: %s" % name)
                in_use = False
                nwfilter = conn.get_nwfilter(name)

                is_conn = wvmInstances(compute.hostname, compute.login,
                                       compute.password, compute.type)
                instances = is_conn.get_instances()
                for inst in instances:
                    #    if in_use: break
                    i_conn = wvmInstance(compute.hostname, compute.login,
                                         compute.password, compute.type, inst)
                    dom_filterrefs = i_conn.get_filterrefs()

                    if name in dom_filterrefs:
                        in_use = True
                        msg = _(
                            "NWFilter is in use by %s. Cannot be deleted." %
                            inst)
                        error_messages.append(msg)
                        addlogmsg(request.user.username, compute.hostname, msg)
                        i_conn.close()
                        break

                is_conn.close()
                if nwfilter and not in_use:
                    nwfilter.undefine()
                    addlogmsg(request.user.username, compute.hostname, msg)

            if 'cln_nwfilter' in request.POST:

                name = request.POST.get('nwfiltername', '')
                cln_name = request.POST.get('cln_name', name + '-clone')

                conn.clone_nwfilter(name, cln_name)
                msg = _("Cloning NWFilter %s as %s" % (name, cln_name))
                addlogmsg(request.user.username, compute.hostname, msg)

        for nwf in conn.get_nwfilters():
            nwfilters_all.append(conn.get_nwfilter_info(nwf))

        conn.close()
    except libvirtError as lib_err:
        error_messages.append(lib_err)
        addlogmsg(request.user.username, compute.hostname, lib_err)
    except Exception as err:
        error_messages.append(err)
        addlogmsg(request.user.username, compute.hostname, err)

    return render(
        request, 'nwfilters.html', {
            'error_messages': error_messages,
            'nwfilters': nwfilters_all,
            'compute': compute
        })
Example #5
0
def instances(request):
    """
    :param request:
    :return:
    """

    error_messages = []
    all_host_vms = {}
    all_user_vms = {}
    computes = Compute.objects.all()

    if not request.user.is_superuser:
        user_instances = UserInstance.objects.filter(user_id=request.user.id)
        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)
                    if conn.get_host_instances():
                        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()
                                all_host_vms[comp.id, comp.name][vm]['is_template'] = check_uuid.is_template
                            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.username, instance.name, msg)
                conn.start(name)
                return HttpResponseRedirect(request.get_full_path())

            if 'poweroff' in request.POST:
                msg = _("Power Off")
                addlogmsg(request.user.username, instance.name, msg)
                conn.shutdown(name)
                return HttpResponseRedirect(request.get_full_path())

            if 'powercycle' in request.POST:
                msg = _("Power Cycle")
                conn.force_shutdown(name)
                conn.start(name)
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path())
            
            if 'getvvfile' in request.POST:
                msg = _("Send console.vv file")
                addlogmsg(request.user.username, instance.name, msg)
                response = HttpResponse(content='', content_type='application/x-virt-viewer', status=200, reason=None, charset='utf-8')
                response.writelines('[virt-viewer]\n')
                response.writelines('type=' + conn.graphics_type(name) + '\n')
                response.writelines('host=' + conn.graphics_listen(name) + '\n')
                response.writelines('port=' + conn.graphics_port(name) + '\n')
                response.writelines('title=' + conn.domain_name(name) + '\n')
                response.writelines('password='******'\n')
                response.writelines('enable-usbredir=1\n')
                response.writelines('disable-effects=all\n')
                response.writelines('secure-attention=ctrl+alt+ins\n')
                response.writelines('release-cursor=ctrl+alt\n')
                response.writelines('fullscreen=1\n')
                response.writelines('delete-this-file=1\n')
                response['Content-Disposition'] = 'attachment; filename="console.vv"'
                return response

            if request.user.is_superuser:

                if 'suspend' in request.POST:
                    msg = _("Suspend")
                    addlogmsg(request.user.username, instance.name, msg)
                    conn.suspend(name)
                    return HttpResponseRedirect(request.get_full_path())

                if 'resume' in request.POST:
                    msg = _("Resume")
                    addlogmsg(request.user.username, instance.name, msg)
                    conn.resume(name)
                    return HttpResponseRedirect(request.get_full_path())

        except libvirtError as lib_err:
            error_messages.append(lib_err)
            addlogmsg(request.user.username, instance.name, lib_err.message)

    return render(request, 'instances.html', locals())
Example #6
0
def instance(request, compute_id, vname):
    """
    :param request:
    :return:
    """

    error_messages = []
    messages = []
    compute = get_object_or_404(Compute, pk=compute_id)
    computes = Compute.objects.all()
    computes_count = len(computes)
    publickeys = UserSSHKey.objects.filter(user_id=request.user.id)
    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, vname=''):
        clone_disk = []
        for disk in disks:
            if disk['image'] is None:
                continue
            if disk['image'].count("-") and disk['image'].rsplit("-", 1)[0] == vname:
                name, suffix = disk['image'].rsplit("-", 1)
                image = name + "-clone" + "-" + suffix
            elif 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
    
    def filesizefstr(size_str):
        if size_str == '':
            return 0
        size_str = size_str.encode('ascii', 'ignore').upper().translate(None, " B")
        if 'K' == size_str[-1]:
            return long(float(size_str[:-1]))<<10
        elif 'M' == size_str[-1]:
            return long(float(size_str[:-1]))<<20
        elif 'G' == size_str[-1]:
            return long(float(size_str[:-1]))<<30
        elif 'T' == size_str[-1]:
            return long(float(size_str[:-1]))<<40
        elif 'P' == size_str[-1]:
            return long(float(size_str[:-1]))<<50
        else:
            return long(float(size_str))

    def get_clone_free_names(size=10):
        prefix = settings.CLONE_INSTANCE_DEFAULT_PREFIX
        free_names = []
        existing_names = [i.name for i in Instance.objects.filter(name__startswith=prefix)]
        index = 1
        while len(free_names) < size:
            new_name = prefix + str(index)
            if new_name not in existing_names:
                free_names.append(new_name)
            index += 1
        return free_names

    def check_user_quota(instance, cpu, memory, disk_size):
        user_instances = UserInstance.objects.filter(user_id=request.user.id, instance__is_template=False)
        instance += len(user_instances)
        for usr_inst in user_instances:
            if connection_manager.host_is_up(usr_inst.instance.compute.type,
                                             usr_inst.instance.compute.hostname):
                conn = wvmInstance(usr_inst.instance.compute,
                                      usr_inst.instance.compute.login,
                                      usr_inst.instance.compute.password,
                                      usr_inst.instance.compute.type,
                                      usr_inst.instance.name)
                cpu += int(conn.get_vcpu())
                memory += int(conn.get_memory())
                for disk in conn.get_disk_device():
                    disk_size += int(disk['size'])>>30
        
        ua = request.user.userattributes
        msg = ""
        if ua.max_instances > 0 and instance > ua.max_instances:
            msg = "instance"
            if settings.QUOTA_DEBUG:
                msg += " (%s > %s)" % (instance, ua.max_instances)
        if ua.max_cpus > 0 and cpu > ua.max_cpus:
            msg = "cpu"
            if settings.QUOTA_DEBUG:
                msg += " (%s > %s)" % (cpu, ua.max_cpus)
        if ua.max_memory > 0 and memory > ua.max_memory:
            msg = "memory"
            if settings.QUOTA_DEBUG:
                msg += " (%s > %s)" % (memory, ua.max_memory)
        if ua.max_disk_size > 0 and disk_size > ua.max_disk_size:
            msg = "disk"
            if settings.QUOTA_DEBUG:
                msg += " (%s > %s)" % (disk_size, ua.max_disk_size)
        return msg

    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()
        title = conn.get_title()
        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, vname)
        console_passwd = conn.get_console_passwd()
        clone_free_names = get_clone_free_names()
        user_quota_msg = check_user_quota(0, 0, 0, 0)

        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:
                conn.start()
                msg = _("Power On")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#poweron')

            if 'powercycle' in request.POST:
                conn.force_shutdown()
                conn.start()
                msg = _("Power Cycle")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#powercycle')

            if 'poweroff' in request.POST:
                conn.shutdown()
                msg = _("Power Off")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#poweroff')

            if 'powerforce' in request.POST:
                conn.force_shutdown()
                msg = _("Force Off")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#powerforce')

            if 'delete' in request.POST:
                if conn.get_status() == 1:
                    conn.force_shutdown()
                if request.POST.get('delete_disk', ''):
                    conn.delete_disk()
                conn.delete()

                instance = Instance.objects.get(compute_id=compute_id, name=vname)
                instance_name = instance.name
                instance.delete()

                try:
                    del_userinstance = UserInstance.objects.filter(instance__compute_id=compute_id, instance__name=vname)
                    del_userinstance.delete()
                except UserInstance.DoesNotExist:
                    pass

                msg = _("Destroy")
                addlogmsg(request.user.username, instance_name, msg)

                return HttpResponseRedirect(reverse('instances'))

            if 'rootpasswd' in request.POST:
                passwd = request.POST.get('passwd', '')
                passwd_hash = crypt.crypt(passwd, '$6$kgPoiREy')
                data = {'action': 'password', 'passwd': passwd_hash, 'vname': vname}

                if conn.get_status() == 5:
                    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    s.connect((compute.hostname, 16510))
                    s.send(json.dumps(data))
                    result = json.loads(s.recv(1024))
                    s.close()
                    msg = _("Reset root password")
                    addlogmsg(request.user.username, instance.name, msg)

                    if result['return'] == 'success':
                        messages.append(msg)
                    else:
                        error_messages.append(msg)
                else:
                    msg = _("Please shutdow down your instance and then try again")
                    error_messages.append(msg)

            if 'addpublickey' in request.POST:
                sshkeyid = request.POST.get('sshkeyid', '')
                publickey = UserSSHKey.objects.get(id=sshkeyid)
                data = {'action': 'publickey', 'key': publickey.keypublic, 'vname': vname}

                if conn.get_status() == 5:
                    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    s.connect((compute.hostname, 16510))
                    s.send(json.dumps(data))
                    result = json.loads(s.recv(1024))
                    s.close()
                    msg = _("Installed new ssh public key %s" % publickey.keyname)
                    addlogmsg(request.user.username, instance.name, msg)

                    if result['return'] == 'success':
                        messages.append(msg)
                    else:
                        error_messages.append(msg)
                else:
                    msg = _("Please shutdow down your instance and then try again")
                    error_messages.append(msg)

            if 'resize' in request.POST:
                new_vcpu = request.POST.get('vcpu', '')
                new_cur_vcpu = request.POST.get('cur_vcpu', '')
                new_memory = request.POST.get('memory', '')
                new_memory_custom = request.POST.get('memory_custom', '')
                if new_memory_custom:
                    new_memory = new_memory_custom
                new_cur_memory = request.POST.get('cur_memory', '')
                new_cur_memory_custom = request.POST.get('cur_memory_custom', '')
                if new_cur_memory_custom:
                    new_cur_memory = new_cur_memory_custom
                disks_new = []
                for disk in disks:
                    input_disk_size = filesizefstr(request.POST.get('disk_size_' + disk['dev'], ''))
                    if input_disk_size > disk['size']+(64<<20):
                        disk['size_new'] = input_disk_size
                        disks_new.append(disk) 
                disk_sum = sum([disk['size']>>30 for disk in disks_new])
                disk_new_sum = sum([disk['size_new']>>30 for disk in disks_new])
                quota_msg = check_user_quota(0, int(new_vcpu)-vcpu, int(new_memory)-memory, disk_new_sum-disk_sum)
                if not request.user.is_superuser and quota_msg:    
                    msg = _("User %s quota reached, cannot resize '%s'!" % (quota_msg, instance.name))
                    error_messages.append(msg)
                else:
                    cur_memory = new_cur_memory
                    memory = new_memory
                    cur_vcpu = new_cur_vcpu
                    vcpu = new_vcpu
                    conn.resize(cur_memory, memory, cur_vcpu, vcpu, disks_new)
                    msg = _("Resize")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#resize')

            if 'umount_iso' in request.POST:
                image = request.POST.get('path', '')
                dev = request.POST.get('umount_iso', '')
                conn.umount_iso(dev, image)
                msg = _("Mount media")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#media')

            if 'mount_iso' in request.POST:
                image = request.POST.get('media', '')
                dev = request.POST.get('mount_iso', '')
                conn.mount_iso(dev, image)
                msg = _("Umount media")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#media')

            if 'snapshot' in request.POST:
                name = request.POST.get('name', '')
                conn.create_snapshot(name)
                msg = _("New snapshot")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#restoresnapshot')

            if 'delete_snapshot' in request.POST:
                snap_name = request.POST.get('name', '')
                conn.snapshot_delete(snap_name)
                msg = _("Delete snapshot")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#restoresnapshot')

            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)
                msg = _("Revert snapshot")
                addlogmsg(request.user.username, instance.name, msg)

            if request.user.is_superuser:
                if 'suspend' in request.POST:
                    conn.suspend()
                    msg = _("Suspend")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#resume')

                if 'resume' in request.POST:
                    conn.resume()
                    msg = _("Resume")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#suspend')

                if 'set_autostart' in request.POST:
                    conn.set_autostart(1)
                    msg = _("Set autostart")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#autostart')

                if 'unset_autostart' in request.POST:
                    conn.set_autostart(0)
                    msg = _("Unset autostart")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#autostart')

                if 'change_xml' in request.POST:
                    exit_xml = request.POST.get('inst_xml', '')
                    if exit_xml:
                        conn._defineXML(exit_xml)
                        msg = _("Edit XML")
                        addlogmsg(request.user.username, instance.name, msg)
                        return HttpResponseRedirect(request.get_full_path() + '#xmledit')

                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")
                            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:
                            msg = _("Set VNC password")
                            addlogmsg(request.user.username, instance.name, msg)
                            return HttpResponseRedirect(request.get_full_path() + '#vncsettings')

                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)
                    msg = _("Set VNC keymap")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#vncsettings')

                if 'set_console_type' in request.POST:
                    console_type = request.POST.get('console_type', '')
                    conn.set_console_type(console_type)
                    msg = _("Set VNC type")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#vncsettings')

                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()
                    msg = _("Migrate")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(reverse('instance', args=[compute_id, vname]))

                if 'change_network' in request.POST:
                    network_data = {}

                    for post in request.POST:
                        if post.startswith('net-'):
                            network_data[post] = request.POST.get(post, '')

                    conn.change_network(network_data)
                    msg = _("Edit network")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#network')

                if 'change_options' in request.POST:
                    instance.is_template = request.POST.get('is_template', False)
                    instance.save()
                    
                    options = {}
                    for post in request.POST:
                        if post in ['title', 'description']:
                            options[post] = request.POST.get(post, '')
                    conn.set_options(options)
                    
                    msg = _("Edit options")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#options')

            if request.user.is_superuser or request.user.userattributes.can_clone_instances:
                if 'clone' in request.POST:
                    clone_data = {}
                    clone_data['name'] = request.POST.get('name', '')

                    disk_sum = sum([disk['size']>>30 for disk in disks])
                    quota_msg = check_user_quota(1, vcpu, memory, disk_sum)
                    check_instance = Instance.objects.filter(name=clone_data['name'])
                    
                    if not request.user.is_superuser and quota_msg:    
                        msg = _("User %s quota reached, cannot create '%s'!" % (quota_msg, clone_data['name']))
                        error_messages.append(msg)
                    elif check_instance:
                        msg = _("Instance '%s' already exists!" % clone_data['name'])
                        error_messages.append(msg)
                    else:
                        for post in request.POST:
                            clone_data[post] = request.POST.get(post, '')

                        new_uuid = conn.clone_instance(clone_data)
                        new_instance = Instance(compute_id=compute_id, name=clone_data['name'], uuid=new_uuid)
                        new_instance.save()
                        userinstance = UserInstance(instance_id=new_instance.id, user_id=request.user.id, is_delete=True)
                        userinstance.save()

                        msg = _("Clone of '%s'" % instance.name)
                        addlogmsg(request.user.username, new_instance.name, msg)
                        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.username, vname, lib_err.message)

    return render(request, 'instance.html', locals())
Example #7
0
def create_instance(request, compute_id):
    """
    :param request:
    :return:
    """

    if not request.user.is_superuser:
        return HttpResponseRedirect(reverse('index'))

    conn = None
    error_messages = []
    storages = []
    networks = []
    meta_prealloc = False
    compute = get_object_or_404(Compute, pk=compute_id)
    flavors = Flavor.objects.filter().order_by('id')

    try:
        conn = wvmCreate(compute.hostname, compute.login, compute.password,
                         compute.type)

        storages = sorted(conn.get_storages(only_actives=True))
        networks = sorted(conn.get_networks())
        nwfilters = conn.get_nwfilters()
        instances = conn.get_instances()
        videos = conn.get_video()
        cache_modes = sorted(conn.get_cache_modes().items())
        default_cache = INSTANCE_VOLUME_DEFAULT_CACHE
        listener_addr = QEMU_CONSOLE_LISTEN_ADDRESSES
        mac_auto = util.randomMAC()
        disk_devices = conn.get_disk_device_types()
        disk_buses = conn.get_disk_bus_types()
        default_bus = INSTANCE_VOLUME_DEFAULT_BUS
    except libvirtError as lib_err:
        error_messages.append(lib_err)

    if conn:
        if not storages:
            msg = _("You haven't defined any storage pools")
            error_messages.append(msg)
        if not networks:
            msg = _("You haven't defined 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('dom_xml', '')
                try:
                    name = util.get_xml_path(xml, '/domain/name')
                except util.etree.Error as err:
                    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=[compute_id, name]))
                    except libvirtError as lib_err:
                        error_messages.append(lib_err.message)
            if 'create' in request.POST:
                volume_list = []

                clone_path = ""
                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 Instance.objects.filter(name__exact=data['name']):
                            messages.warning(
                                request,
                                _("There is an instance with same name. Are you sure?"
                                  ))
                    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)
                                    volume = dict()
                                    volume['path'] = path
                                    volume['type'] = conn.get_volume_type(path)
                                    volume['device'] = 'disk'
                                    volume['bus'] = 'virtio'
                                    volume_list.append(volume)
                                except libvirtError as lib_err:
                                    error_messages.append(lib_err.message)
                        elif data['template']:
                            templ_path = conn.get_volume_path(data['template'])
                            dest_vol = conn.get_volume_path(
                                data["name"] + ".img", data['storage'])
                            if dest_vol:
                                error_msg = _(
                                    "Image has already exist. Please check volumes or change instance name"
                                )
                                error_messages.append(error_msg)
                            else:
                                clone_path = conn.clone_from_template(
                                    data['name'],
                                    templ_path,
                                    data['storage'],
                                    metadata=meta_prealloc)
                                volume = dict()
                                volume['path'] = clone_path
                                volume['type'] = conn.get_volume_type(
                                    clone_path)
                                volume['device'] = 'disk'
                                volume['bus'] = 'virtio'
                                volume_list.append(volume)
                        else:
                            if not data['images']:
                                error_msg = _(
                                    "First you need to create or select an image"
                                )
                                error_messages.append(error_msg)
                            else:
                                for idx, vol in enumerate(
                                        data['images'].split(',')):
                                    try:

                                        path = conn.get_volume_path(vol)
                                        volume = dict()
                                        volume['path'] = path
                                        volume['type'] = conn.get_volume_type(
                                            path)
                                        volume['device'] = request.POST.get(
                                            'device' + str(idx), '')
                                        volume['bus'] = request.POST.get(
                                            'bus' + str(idx), '')
                                        volume_list.append(volume)
                                    except libvirtError as lib_err:
                                        error_messages.append(lib_err.message)
                        if data['cache_mode'] not in conn.get_cache_modes():
                            error_msg = _("Invalid cache mode")
                            error_messages.append(error_msg)
                        if not error_messages:
                            uuid = util.randomUUID()
                            try:
                                conn.create_instance(
                                    data['name'], data['memory'], data['vcpu'],
                                    data['host_model'], uuid, volume_list,
                                    data['cache_mode'], data['networks'],
                                    data['virtio'], data["listener_addr"],
                                    data["nwfilter"], data["video"],
                                    data["console_pass"], data['mac'],
                                    data['qemu_ga'])
                                create_instance = Instance(
                                    compute_id=compute_id,
                                    name=data['name'],
                                    uuid=uuid)
                                create_instance.save()
                                msg = _("Instance is created.")
                                messages.success(request, msg)
                                addlogmsg(request.user.username,
                                          create_instance.name, msg)
                                return HttpResponseRedirect(
                                    reverse('instance',
                                            args=[compute_id, data['name']]))
                            except libvirtError as lib_err:
                                if data['hdd_size'] or volume_list.count() > 0:
                                    for vol in volume_list:
                                        conn.delete_volume(vol['path'])
                                error_messages.append(lib_err)
        conn.close()
    return render(request, 'create_instance.html', locals())
Example #8
0
def instance(request, compute_id, vname):
    """
    :param request:
    :return:
    """

    error_messages = []
   #messages = []
    compute = get_object_or_404(Compute, pk=compute_id)
    computes = Compute.objects.all().order_by('name')
    computes_count = computes.count()
    users = User.objects.all().order_by('username')
    publickeys = UserSSHKey.objects.filter(user_id=request.user.id)
    keymaps = settings.QEMU_KEYMAPS
    console_types = settings.QEMU_CONSOLE_TYPES
    console_listen_addresses = settings.QEMU_CONSOLE_LISTEN_ADDRESSES
    try:
        userinstance = UserInstance.objects.get(instance__compute_id=compute_id,
                                               instance__name=vname,
                                               user__id=request.user.id)
    except UserInstance.DoesNotExist:
        userinstance = None

    if not request.user.is_superuser:
        if not userinstance:
            return HttpResponseRedirect(reverse('index'))

    def show_clone_disk(disks, vname=''):
        clone_disk = []
        for disk in disks:
            if disk['image'] is None:
                continue
            if disk['image'].count("-") and disk['image'].rsplit("-", 1)[0] == vname:
                name, suffix = disk['image'].rsplit("-", 1)
                image = name + "-clone" + "-" + suffix
            elif 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
    
    def filesizefstr(size_str):
        if size_str == '':
            return 0
        size_str = size_str.encode('ascii', 'ignore').upper().translate(None, " B")
        if 'K' == size_str[-1]:
            return long(float(size_str[:-1]))<<10
        elif 'M' == size_str[-1]:
            return long(float(size_str[:-1]))<<20
        elif 'G' == size_str[-1]:
            return long(float(size_str[:-1]))<<30
        elif 'T' == size_str[-1]:
            return long(float(size_str[:-1]))<<40
        elif 'P' == size_str[-1]:
            return long(float(size_str[:-1]))<<50
        else:
            return long(float(size_str))

    def get_clone_free_names(size=10):
        prefix = settings.CLONE_INSTANCE_DEFAULT_PREFIX
        free_names = []
        existing_names = [i.name for i in Instance.objects.filter(name__startswith=prefix)]
        index = 1
        while len(free_names) < size:
            new_name = prefix + str(index)
            if new_name not in existing_names:
                free_names.append(new_name)
            index += 1
        return free_names

    def check_user_quota(instance, cpu, memory, disk_size):
        user_instances = UserInstance.objects.filter(user_id=request.user.id, instance__is_template=False)
        instance += user_instances.count()
        for usr_inst in user_instances:
            if connection_manager.host_is_up(usr_inst.instance.compute.type,
                                             usr_inst.instance.compute.hostname):
                conn = wvmInstance(usr_inst.instance.compute,
                                      usr_inst.instance.compute.login,
                                      usr_inst.instance.compute.password,
                                      usr_inst.instance.compute.type,
                                      usr_inst.instance.name)
                cpu += int(conn.get_vcpu())
                memory += int(conn.get_memory())
                for disk in conn.get_disk_device():
                    if disk['size']:
                        disk_size += int(disk['size'])>>30
        
        ua = request.user.userattributes
        msg = ""
        if ua.max_instances > 0 and instance > ua.max_instances:
            msg = "instance"
            if settings.QUOTA_DEBUG:
                msg += " (%s > %s)" % (instance, ua.max_instances)
        if ua.max_cpus > 0 and cpu > ua.max_cpus:
            msg = "cpu"
            if settings.QUOTA_DEBUG:
                msg += " (%s > %s)" % (cpu, ua.max_cpus)
        if ua.max_memory > 0 and memory > ua.max_memory:
            msg = "memory"
            if settings.QUOTA_DEBUG:
                msg += " (%s > %s)" % (memory, ua.max_memory)
        if ua.max_disk_size > 0 and disk_size > ua.max_disk_size:
            msg = "disk"
            if settings.QUOTA_DEBUG:
                msg += " (%s > %s)" % (disk_size, ua.max_disk_size)
        return msg

    def get_new_disk_dev(disks, bus):
        if bus == "virtio":
            dev_base = "vd"
        else:
            dev_base = "sd"
        existing_devs = [ disk['dev'] for disk in disks ]
        for l in string.lowercase:
            dev = dev_base + l
            if dev not in existing_devs:
                return dev
        raise Exception(_('None available device name'))

    def get_network_tuple(network_source_str):
        network_source_pack = network_source_str.split(":", 1)
        if len(network_source_pack) > 1:
            return (network_source_pack[1], network_source_pack[0])
        else:
            return (network_source_pack[0], 'net')
            
    try:
        conn = wvmInstance(compute.hostname,
                           compute.login,
                           compute.password,
                           compute.type,
                           vname)
        compute_networks = sorted(conn.get_networks())
        compute_interfaces = sorted(conn.get_ifaces())
        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()
        title = conn.get_title()
        description = conn.get_description()
        disks = conn.get_disk_device()
        media = conn.get_media_device()
        networks = conn.get_net_device()
        if len(media) != 0:
            media_iso = sorted(conn.get_iso_media())
        else:
            media_iso = []
        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()
        console_listen_address = conn.get_console_listen_addr()
        snapshots = sorted(conn.get_snapshot(), reverse=True, key=lambda k:k['date'])
        inst_xml = conn._XMLDesc(VIR_DOMAIN_XML_SECURE)
        has_managed_save_image = conn.get_managed_save_image()
        clone_disks = show_clone_disk(disks, vname)
        console_passwd = conn.get_console_passwd()
        clone_free_names = get_clone_free_names()
        user_quota_msg = check_user_quota(0, 0, 0, 0)
        storages = sorted(conn.get_storages())
        cache_modes = sorted(conn.get_cache_modes().items())
        default_cache = settings.INSTANCE_VOLUME_DEFAULT_CACHE
        default_format = settings.INSTANCE_VOLUME_DEFAULT_FORMAT
        formats = conn.get_image_formats()


        busses = conn.get_busses()
        default_bus = settings.INSTANCE_VOLUME_DEFAULT_BUS
        show_access_root_password = settings.SHOW_ACCESS_ROOT_PASSWORD
        show_access_ssh_keys = settings.SHOW_ACCESS_SSH_KEYS
        clone_instance_auto_name = settings.CLONE_INSTANCE_AUTO_NAME

        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()

        userinstances = UserInstance.objects.filter(instance=instance).order_by('user__username')

        if request.method == 'POST':
            if 'poweron' in request.POST:
                conn.start()
                msg = _("Power On")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#poweron')

            if 'powercycle' in request.POST:
                conn.force_shutdown()
                conn.start()
                msg = _("Power Cycle")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#powercycle')

            if 'poweroff' in request.POST:
                conn.shutdown()
                msg = _("Power Off")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#poweroff')

            if 'powerforce' in request.POST:
                conn.force_shutdown()
                msg = _("Force Off")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#powerforce')

            if 'delete' in request.POST and (request.user.is_superuser or userinstance.is_delete):
                if conn.get_status() == 1:
                    conn.force_shutdown()
                if request.POST.get('delete_disk', ''):
                    for snap in snapshots:
                        conn.snapshot_delete(snap['name'])
                    conn.delete_disk()
                conn.delete()

                instance = Instance.objects.get(compute_id=compute_id, name=vname)
                instance_name = instance.name
                instance.delete()

                try:
                    del_userinstance = UserInstance.objects.filter(instance__compute_id=compute_id, instance__name=vname)
                    del_userinstance.delete()
                except UserInstance.DoesNotExist:
                    pass

                msg = _("Destroy")
                addlogmsg(request.user.username, instance_name, msg)

                return HttpResponseRedirect(reverse('instances'))

            if 'rootpasswd' in request.POST:
                passwd = request.POST.get('passwd', '')
                passwd_hash = crypt.crypt(passwd, '$6$kgPoiREy')
                data = {'action': 'password', 'passwd': passwd_hash, 'vname': vname}

                if conn.get_status() == 5:
                    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    s.connect((compute.hostname, 16510))
                    s.send(json.dumps(data))
                    result = json.loads(s.recv(1024))
                    s.close()
                    msg = _("Reset root password")
                    addlogmsg(request.user.username, instance.name, msg)

                    if result['return'] == 'success':
                        messages.success(request, msg)
                    else:
                        error_messages.append(msg)
                else:
                    msg = _("Please shutdow down your instance and then try again")
                    error_messages.append(msg)

            if 'addpublickey' in request.POST:
                sshkeyid = request.POST.get('sshkeyid', '')
                publickey = UserSSHKey.objects.get(id=sshkeyid)
                data = {'action': 'publickey', 'key': publickey.keypublic, 'vname': vname}

                if conn.get_status() == 5:
                    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    s.connect((compute.hostname, 16510))
                    s.send(json.dumps(data))
                    result = json.loads(s.recv(1024))
                    s.close()
                    msg = _("Installed new ssh public key %s" % publickey.keyname)
                    addlogmsg(request.user.username, instance.name, msg)

                    if result['return'] == 'success':
                        messages.success(request, msg)
                    else:
                        error_messages.append(msg)
                else:
                    msg = _("Please shutdow down your instance and then try again")
                    error_messages.append(msg)

            if 'resize' in request.POST and (request.user.is_superuser or request.user.is_staff or userinstance.is_change):
                new_vcpu = request.POST.get('vcpu', '')
                new_cur_vcpu = request.POST.get('cur_vcpu', '')
                new_memory = request.POST.get('memory', '')
                new_memory_custom = request.POST.get('memory_custom', '')
                if new_memory_custom:
                    new_memory = new_memory_custom
                new_cur_memory = request.POST.get('cur_memory', '')
                new_cur_memory_custom = request.POST.get('cur_memory_custom', '')
                if new_cur_memory_custom:
                    new_cur_memory = new_cur_memory_custom
                disks_new = []
                for disk in disks:
                    input_disk_size = filesizefstr(request.POST.get('disk_size_' + disk['dev'], ''))
                    if input_disk_size > disk['size']+(64<<20):
                        disk['size_new'] = input_disk_size
                        disks_new.append(disk) 
                disk_sum = sum([disk['size']>>30 for disk in disks_new])
                disk_new_sum = sum([disk['size_new']>>30 for disk in disks_new])
                quota_msg = check_user_quota(0, int(new_vcpu)-vcpu, int(new_memory)-memory, disk_new_sum-disk_sum)
                if not request.user.is_superuser and quota_msg:    
                    msg = _("User %s quota reached, cannot resize '%s'!" % (quota_msg, instance.name))
                    error_messages.append(msg)
                else:
                    cur_memory = new_cur_memory
                    memory = new_memory
                    cur_vcpu = new_cur_vcpu
                    vcpu = new_vcpu
                    conn.resize(cur_memory, memory, cur_vcpu, vcpu, disks_new)
                    msg = _("Resize")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#resize')

            if 'addvolume' in request.POST and (request.user.is_superuser or userinstance.is_change):
                connCreate = wvmCreate(compute.hostname,
                                   compute.login,
                                   compute.password,
                                   compute.type)
                storage = request.POST.get('storage', '')
                name = request.POST.get('name', '')
                format = request.POST.get('format', '')
                size = request.POST.get('size', 0)
                meta_prealloc = request.POST.get('meta_prealloc', False)
                bus = request.POST.get('bus', '')
                cache = request.POST.get('cache', '')
                target = get_new_disk_dev(disks, bus)
                
                path = connCreate.create_volume(storage, name, size, format, meta_prealloc)
                conn.attach_disk(path, target, subdriver=format, cache=cache, targetbus=bus)
                msg = _('Attach new disk')
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#resize')

            if 'umount_iso' in request.POST:
                image = request.POST.get('path', '')
                dev = request.POST.get('umount_iso', '')
                conn.umount_iso(dev, image)
                msg = _("Mount media")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#media')

            if 'mount_iso' in request.POST:
                image = request.POST.get('media', '')
                dev = request.POST.get('mount_iso', '')
                conn.mount_iso(dev, image)
                msg = _("Umount media")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#media')

            if 'snapshot' in request.POST:
                name = request.POST.get('name', '')
                conn.create_snapshot(name)
                msg = _("New snapshot")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#restoresnapshot')

            if 'delete_snapshot' in request.POST:
                snap_name = request.POST.get('name', '')
                conn.snapshot_delete(snap_name)
                msg = _("Delete snapshot")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#restoresnapshot')

            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.success(request, msg)
                msg = _("Revert snapshot")
                addlogmsg(request.user.username, instance.name, msg)

            if request.user.is_superuser:
                if 'suspend' in request.POST:
                    conn.suspend()
                    msg = _("Suspend")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#resume')

                if 'resume' in request.POST:
                    conn.resume()
                    msg = _("Resume")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#suspend')

                if 'set_autostart' in request.POST:
                    conn.set_autostart(1)
                    msg = _("Set autostart")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#autostart')

                if 'unset_autostart' in request.POST:
                    conn.set_autostart(0)
                    msg = _("Unset autostart")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#autostart')

                if 'change_xml' in request.POST:
                    exit_xml = request.POST.get('inst_xml', '')
                    if exit_xml:
                        conn._defineXML(exit_xml)
                        msg = _("Edit XML")
                        addlogmsg(request.user.username, instance.name, msg)
                        return HttpResponseRedirect(request.get_full_path() + '#xmledit')

            if request.user.is_superuser or userinstance.is_vnc:
                if 'set_console_passwd' in request.POST:
                    if request.POST.get('auto_pass', ''):
                        passwd = randomPasswd()
                    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:
                            msg = _("Set VNC password")
                            addlogmsg(request.user.username, instance.name, msg)
                            return HttpResponseRedirect(request.get_full_path() + '#vncsettings')

                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)
                    msg = _("Set VNC keymap")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#vncsettings')

                if 'set_console_type' in request.POST:
                    console_type = request.POST.get('console_type', '')
                    conn.set_console_type(console_type)
                    msg = _("Set VNC type")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#vncsettings')
                
                if 'set_console_listen_address' in request.POST:
                    console_type = request.POST.get('console_listen_address', '')
                    conn.set_console_listen_addr(console_type)
                    msg = _("Set VNC listen address")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#vncsettings')

            if request.user.is_superuser:
                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)
                    offline = request.POST.get('offline_migrate', 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, offline)
                    instance.compute = new_compute
                    instance.save()
                    conn_migrate.close()
                    if autostart:
                        conn_new = wvmInstance(new_compute.hostname,
                                               new_compute.login,
                                               new_compute.password,
                                               new_compute.type,
                                               vname)
                        conn_new.set_autostart(1)
                        conn_new.close()
                    msg = _("Migrate to %s" % new_compute.hostname)
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(reverse('instance', args=[compute_id, vname]))

                if 'change_network' in request.POST:
                    network_data = {}

                    for post in request.POST:
                        if post.startswith('net-source-'):
                            (source, source_type) = get_network_tuple(request.POST.get(post))
                            network_data[post] = source
                            network_data[post + '-type'] = source_type
                        elif post.startswith('net-'):
                            network_data[post] = request.POST.get(post, '')

                    conn.change_network(network_data)
                    msg = _("Edit network")
                    addlogmsg(request.user.username, instance.name, msg)
                    msg = _("Network Devices are changed. Please reboot instance to activate.")
                    messages.success(request, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#network')

                if 'add_network' in request.POST:
                    mac = request.POST.get('add-net-mac')
                    (source, source_type) = get_network_tuple(request.POST.get('add-net-network'))

                    conn.add_network(mac, source, source_type)
                    msg = _("Edit network")
                    addlogmsg(request.user.username, instance.name, msg)
                    msg = _("Network Devices are changed. Please reboot instance to activate.")
                    messages.success(request, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#network')
                
                if 'add_owner' in request.POST:
                    user_id = int(request.POST.get('user_id', ''))
                    
                    if settings.ALLOW_INSTANCE_MULTIPLE_OWNER:
                        check_inst = UserInstance.objects.filter(instance=instance, user_id=user_id)
                    else:
                        check_inst = UserInstance.objects.filter(instance=instance)
                    
                    if check_inst:
                        msg = _("Owner already added")
                        error_messages.append(msg)
                    else:
                        add_user_inst = UserInstance(instance=instance, user_id=user_id)
                        add_user_inst.save()
                        msg = _("Added owner %d" % user_id)
                        addlogmsg(request.user.username, instance.name, msg)
                        return HttpResponseRedirect(request.get_full_path() + '#users')

                if 'del_owner' in request.POST:
                    userinstance_id = int(request.POST.get('userinstance', ''))
                    userinstance = UserInstance.objects.get(pk=userinstance_id)
                    userinstance.delete()
                    msg = _("Deleted owner %d" % userinstance_id)
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#users')


            if request.user.is_superuser or request.user.userattributes.can_clone_instances:
                if 'clone' in request.POST:
                    clone_data = {}
                    clone_data['name'] = request.POST.get('name', '')

                    disk_sum = sum([disk['size']>>30 for disk in disks])
                    quota_msg = check_user_quota(1, vcpu, memory, disk_sum)
                    check_instance = Instance.objects.filter(name=clone_data['name'])
                    
                    for post in request.POST:
                        clone_data[post] = request.POST.get(post, '').strip()
                    
                    if clone_instance_auto_name and not clone_data['name']:
                        auto_vname = clone_free_names[0]
                        clone_data['name'] = auto_vname
                        clone_data['clone-net-mac-0'] = _get_dhcp_mac_address(auto_vname)
                        for post in clone_data.keys():
                            if post.startswith('disk-'):
                                disk_name = clone_data[post]
                                if "-" in disk_name:
                                    suffix = disk_name.split("-")[-1]
                                    disk_name = '-'.join((auto_vname, suffix))
                                else:
                                    suffix = disk_name.split(".")[-1]
                                    disk_name = '.'.join((auto_vname, suffix))
                                clone_data[post] = disk_name
                    
                    if not request.user.is_superuser and quota_msg:
                        msg = _("User %s quota reached, cannot create '%s'!" % (quota_msg, clone_data['name']))
                        error_messages.append(msg)
                    elif check_instance:
                        msg = _("Instance '%s' already exists!" % clone_data['name'])
                        error_messages.append(msg)
                    elif not re.match(r'^[a-zA-Z0-9-]+$', clone_data['name']):
                        msg = _("Instance name '%s' contains invalid characters!" % clone_data['name'])
                        error_messages.append(msg)
                    elif not re.match(r'^([0-9A-F]{2})(\:?[0-9A-F]{2}){5}$', clone_data['clone-net-mac-0'], re.IGNORECASE):
                        msg = _("Instance mac '%s' invalid format!" % clone_data['clone-net-mac-0'])
                        error_messages.append(msg)
                    else:
                        new_uuid = conn.clone_instance(clone_data)
                        new_instance = Instance(compute_id=compute_id, name=clone_data['name'], uuid=new_uuid)
                        new_instance.save()
                        userinstance = UserInstance(instance_id=new_instance.id, user_id=request.user.id, is_delete=True)
                        userinstance.save()

                        msg = _("Clone of '%s'" % instance.name)
                        addlogmsg(request.user.username, new_instance.name, msg)
                        return HttpResponseRedirect(reverse('instance', args=[compute_id, clone_data['name']]))

                if 'change_options' in request.POST:
                    instance.is_template = request.POST.get('is_template', False)
                    instance.save()
                    
                    options = {}
                    for post in request.POST:
                        if post in ['title', 'description']:
                            options[post] = request.POST.get(post, '')
                    conn.set_options(options)
                    
                    msg = _("Edit options")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#options')

        conn.close()

    except libvirtError as lib_err:
        error_messages.append(lib_err.message)
        addlogmsg(request.user.username, vname, lib_err.message)

    return render(request, 'instance.html', locals())
Example #9
0
def instances(request):
    """
    :param request:
    :return:
    """

    error_messages = []
    all_host_vms = {}
    all_user_vms = {}
    computes = Compute.objects.all()

    def get_userinstances_info(instance):
        info = {}
        uis = UserInstance.objects.filter(instance=instance)
        info['count'] = uis.count()
        if info['count'] > 0:
            info['first_user'] = uis[0]
        else:
            info['first_user'] = None
        return info

    def refresh_instance_database(comp, vm, info):
        instances = Instance.objects.filter(name=vm)
        if instances.count() > 1:
            for i in instances:
                user_instances_count = UserInstance.objects.filter(
                    instance=i).count()
                if user_instances_count == 0:
                    addlogmsg(request.user.username, i.name,
                              _("Deleting due to multiple records."))
                    i.delete()

        try:
            check_uuid = Instance.objects.get(compute_id=comp["id"], name=vm)
            if check_uuid.uuid != info['uuid']:
                check_uuid.save()

            all_host_vms[comp_info["id"], comp_info["name"],
                         comp_info["status"], comp_info["cpu"],
                         comp_info["mem_size"], comp_info["mem_perc"]][vm][
                             'is_template'] = check_uuid.is_template
            all_host_vms[comp_info["id"], comp_info["name"],
                         comp_info["status"], comp_info["cpu"],
                         comp_info["mem_size"], comp_info["mem_perc"]][vm][
                             'userinstances'] = get_userinstances_info(
                                 check_uuid)
        except Instance.DoesNotExist:
            check_uuid = Instance(compute_id=comp["id"],
                                  name=vm,
                                  uuid=info['uuid'])
            check_uuid.save()

    if not request.user.is_superuser:
        user_instances = UserInstance.objects.filter(user_id=request.user.id)
        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:
            status = connection_manager.host_is_up(comp.type, comp.hostname)
            if status:
                try:
                    conn = wvmHostDetails(comp, comp.login, comp.password,
                                          comp.type)
                    comp_node_info = conn.get_node_info()
                    comp_mem = conn.get_memory_usage()
                    comp_instances = conn.get_host_instances(True)

                    if comp_instances:
                        comp_info = {
                            "id": comp.id,
                            "name": comp.name,
                            "status": status,
                            "cpu": comp_node_info[3],
                            "mem_size": comp_node_info[2],
                            "mem_perc": comp_mem['percent']
                        }
                        all_host_vms[comp_info["id"], comp_info["name"],
                                     comp_info["status"], comp_info["cpu"],
                                     comp_info["mem_size"],
                                     comp_info["mem_perc"]] = comp_instances
                        for vm, info in comp_instances.items():
                            refresh_instance_database(comp_info, vm, info)

                    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.username, instance.name, msg)
                conn.start(name)
                return HttpResponseRedirect(request.get_full_path())

            if 'poweroff' in request.POST:
                msg = _("Power Off")
                addlogmsg(request.user.username, instance.name, msg)
                conn.shutdown(name)
                return HttpResponseRedirect(request.get_full_path())

            if 'powercycle' in request.POST:
                msg = _("Power Cycle")
                conn.force_shutdown(name)
                conn.start(name)
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path())

            if 'getvvfile' in request.POST:
                msg = _("Send console.vv file")
                addlogmsg(request.user.username, instance.name, msg)
                response = HttpResponse(
                    content='',
                    content_type='application/x-virt-viewer',
                    status=200,
                    reason=None,
                    charset='utf-8')
                response.writelines('[virt-viewer]\n')
                response.writelines('type=' + conn.graphics_type(name) + '\n')
                response.writelines('host=' + conn.graphics_listen(name) +
                                    '\n')
                response.writelines('port=' + conn.graphics_port(name) + '\n')
                response.writelines('title=' + conn.domain_name(name) + '\n')
                response.writelines('password='******'\n')
                response.writelines('enable-usbredir=1\n')
                response.writelines('disable-effects=all\n')
                response.writelines('secure-attention=ctrl+alt+ins\n')
                response.writelines('release-cursor=ctrl+alt\n')
                response.writelines('fullscreen=1\n')
                response.writelines('delete-this-file=1\n')
                response[
                    'Content-Disposition'] = 'attachment; filename="console.vv"'
                return response

            if request.user.is_superuser:

                if 'suspend' in request.POST:
                    msg = _("Suspend")
                    addlogmsg(request.user.username, instance.name, msg)
                    conn.suspend(name)
                    return HttpResponseRedirect(request.get_full_path())

                if 'resume' in request.POST:
                    msg = _("Resume")
                    addlogmsg(request.user.username, instance.name, msg)
                    conn.resume(name)
                    return HttpResponseRedirect(request.get_full_path())

        except libvirtError as lib_err:
            error_messages.append(lib_err)
            addlogmsg(request.user.username, instance.name, lib_err.message)

    return render(request, 'instances.html', locals())
Example #10
0
def instances(request):
    """
    :param request:
    :return:
    """

    if not request.user.is_authenticated():
        return HttpResponseRedirect(reverse('index'))

    error_messages = []
    all_host_vms = {}
    all_host_vms_bis = {}
    all_user_vms = {}
    computes = Compute.objects.all()

    if not request.user.is_superuser:
        user_instances = UserInstance.objects.filter(user_id=request.user.id)
        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)
                    if conn.get_host_instances():
                        all_host_vms[comp.id,
                                     comp.name] = conn.get_host_instances()
                        all_host_vms_bis[comp.id, comp.name] = []
                        for vm, info in all_host_vms[comp.id,
                                                     comp.name].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()
                            all_host_vms_bis[comp.id, comp.name].append(
                                (Instance.objects.get(compute_id=comp.id,
                                                      name=vm), info))
                    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.username, instance.name, msg)
                conn.start(name)
                return HttpResponseRedirect(request.get_full_path())

            if 'poweroff' in request.POST:
                msg = _("Power Off")
                addlogmsg(request.user.username, instance.name, msg)
                conn.shutdown(name)
                return HttpResponseRedirect(request.get_full_path())

            if 'powercycle' in request.POST:
                msg = _("Power Cycle")
                conn.force_shutdown(name)
                conn.start(name)
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path())

            if request.user.is_superuser:

                if 'suspend' in request.POST:
                    msg = _("Suspend")
                    addlogmsg(request.user.username, instance.name, msg)
                    conn.suspend(name)
                    return HttpResponseRedirect(request.get_full_path())

                if 'resume' in request.POST:
                    msg = _("Resume")
                    addlogmsg(request.user.username, instance.name, msg)
                    conn.resume(name)
                    return HttpResponseRedirect(request.get_full_path())

        except libvirtError as lib_err:
            error_messages.append(lib_err)
            addlogmsg(request.user.username, instance.name, lib_err.message)

    return render(request, 'instances.html', locals())
Example #11
0
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.filter(user_id=request.user.id)
        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)
                    if conn.get_host_instances():
                        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.username, instance.name, msg)
                conn.start(name)
                return HttpResponseRedirect(request.get_full_path())

            if 'poweroff' in request.POST:
                msg = _("Power Off")
                addlogmsg(request.user.username, instance.name, msg)
                conn.shutdown(name)
                return HttpResponseRedirect(request.get_full_path())

            if 'powercycle' in request.POST:
                msg = _("Power Cycle")
                conn.force_shutdown(name)
                conn.start(name)
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path())

            if 'getvvfile' in request.POST:
                msg = _("Send console.vv file")
                addlogmsg(request.user.username, instance.name, msg)
                response = HttpResponse(
                    content='',
                    content_type='application/x-virt-viewer',
                    status=200,
                    reason=None,
                    charset='utf-8')
                response.writelines('[virt-viewer]\n')
                response.writelines('type=' + conn.graphics_type(name) + '\n')
                response.writelines('host=' + conn.graphics_listen(name) +
                                    '\n')
                response.writelines('port=' + conn.graphics_port(name) + '\n')
                response.writelines('title=' + conn.domain_name(name) + '\n')
                response.writelines('password='******'\n')
                response.writelines('enable-usbredir=1\n')
                response.writelines('disable-effects=all\n')
                response.writelines('secure-attention=ctrl+alt+ins\n')
                response.writelines('release-cursor=ctrl+alt\n')
                response.writelines('fullscreen=1\n')
                response.writelines('delete-this-file=1\n')
                response[
                    'Content-Disposition'] = 'attachment; filename="console.vv"'
                return response

            if request.user.is_superuser:

                if 'suspend' in request.POST:
                    msg = _("Suspend")
                    addlogmsg(request.user.username, instance.name, msg)
                    conn.suspend(name)
                    return HttpResponseRedirect(request.get_full_path())

                if 'resume' in request.POST:
                    msg = _("Resume")
                    addlogmsg(request.user.username, instance.name, msg)
                    conn.resume(name)
                    return HttpResponseRedirect(request.get_full_path())

        except libvirtError as lib_err:
            error_messages.append(lib_err)
            addlogmsg(request.user.username, instance.name, lib_err.message)

    return render(request, 'instances.html', locals())
Example #12
0
def instance(request, compute_id, vname):
    """
    :param request:
    :return:
    """

    error_messages = []
    messages = []
    compute = get_object_or_404(Compute, pk=compute_id)
    computes = Compute.objects.all()
    computes_count = len(computes)
    publickeys = UserSSHKey.objects.filter(user_id=request.user.id)
    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

    def filesizefstr(size_str):
        if size_str == "":
            return 0
        size_str = size_str.encode("ascii", "ignore").upper().translate(None, " B")
        if "K" == size_str[-1]:
            return long(float(size_str[:-1])) << 10
        elif "M" == size_str[-1]:
            return long(float(size_str[:-1])) << 20
        elif "G" == size_str[-1]:
            return long(float(size_str[:-1])) << 30
        elif "T" == size_str[-1]:
            return long(float(size_str[:-1])) << 40
        elif "P" == size_str[-1]:
            return long(float(size_str[:-1])) << 50
        else:
            return long(float(size_str))

    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:
                conn.start()
                msg = _("Power On")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + "#poweron")

            if "powercycle" in request.POST:
                conn.force_shutdown()
                conn.start()
                msg = _("Power Cycle")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + "#powercycle")

            if "poweroff" in request.POST:
                conn.shutdown()
                msg = _("Power Off")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + "#poweroff")

            if "powerforce" in request.POST:
                conn.force_shutdown()
                msg = _("Force Off")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + "#powerforce")

            if "delete" in request.POST:
                if conn.get_status() == 1:
                    conn.force_shutdown()
                if request.POST.get("delete_disk", ""):
                    conn.delete_disk()
                conn.delete()

                instance = Instance.objects.get(compute_id=compute_id, name=vname)
                instance_name = instance.name
                instance.delete()

                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.delete()
                    except UserInstance.DoesNotExist:
                        pass

                msg = _("Destroy")
                addlogmsg(request.user.username, instance_name, msg)

                return HttpResponseRedirect(reverse("instances"))

            if "rootpasswd" in request.POST:
                passwd = request.POST.get("passwd", "")
                passwd_hash = crypt.crypt(passwd, "$6$kgPoiREy")
                data = {"action": "password", "passwd": passwd_hash, "vname": vname}

                if conn.get_status() == 5:
                    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    s.connect((compute.hostname, 16510))
                    s.send(json.dumps(data))
                    result = json.loads(s.recv(1024))
                    s.close()
                    msg = _("Reset root password")
                    addlogmsg(request.user.username, instance.name, msg)

                    if result["return"] == "success":
                        messages.append(msg)
                    else:
                        error_messages.append(msg)
                else:
                    msg = _("Please shutdow down your instance and then try again")
                    error_messages.append(msg)

            if "addpublickey" in request.POST:
                sshkeyid = request.POST.get("sshkeyid", "")
                publickey = UserSSHKey.objects.get(id=sshkeyid)
                data = {"action": "publickey", "key": publickey.keypublic, "vname": vname}

                if conn.get_status() == 5:
                    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    s.connect((compute.hostname, 16510))
                    s.send(json.dumps(data))
                    result = json.loads(s.recv(1024))
                    s.close()
                    msg = _("Installed new ssh public key %s" % publickey.keyname)
                    addlogmsg(request.user.username, instance.name, msg)

                    if result["return"] == "success":
                        messages.append(msg)
                    else:
                        error_messages.append(msg)
                else:
                    msg = _("Please shutdow down your instance and then try again")
                    error_messages.append(msg)

            if "resize" in request.POST:
                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
                disks_new = []
                for disk in disks:
                    input_disk_size = filesizefstr(request.POST.get("disk_size_" + disk["dev"], ""))
                    if input_disk_size > disk["size"] + (64 << 20):
                        disk["size_new"] = input_disk_size
                        disks_new.append(disk)
                conn.resize(cur_memory, memory, cur_vcpu, vcpu, disks_new)
                msg = _("Resize")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + "#resize")

            if "umount_iso" in request.POST:
                image = request.POST.get("path", "")
                dev = request.POST.get("umount_iso", "")
                conn.umount_iso(dev, image)
                msg = _("Mount media")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + "#media")

            if "mount_iso" in request.POST:
                image = request.POST.get("media", "")
                dev = request.POST.get("mount_iso", "")
                conn.mount_iso(dev, image)
                msg = _("Umount media")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + "#media")

            if "snapshot" in request.POST:
                name = request.POST.get("name", "")
                conn.create_snapshot(name)
                msg = _("New snapshot")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + "#restoresnapshot")

            if "delete_snapshot" in request.POST:
                snap_name = request.POST.get("name", "")
                conn.snapshot_delete(snap_name)
                msg = _("Delete snapshot")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + "#restoresnapshot")

            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)
                msg = _("Revert snapshot")
                addlogmsg(request.user.username, instance.name, msg)

            if request.user.is_superuser:
                if "suspend" in request.POST:
                    conn.suspend()
                    msg = _("Suspend")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + "#resume")

                if "resume" in request.POST:
                    conn.resume()
                    msg = _("Resume")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + "#suspend")

                if "set_autostart" in request.POST:
                    conn.set_autostart(1)
                    msg = _("Set autostart")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + "#autostart")

                if "unset_autostart" in request.POST:
                    conn.set_autostart(0)
                    msg = _("Unset autostart")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + "#autostart")

                if "change_xml" in request.POST:
                    exit_xml = request.POST.get("inst_xml", "")
                    if exit_xml:
                        conn._defineXML(exit_xml)
                        msg = _("Edit XML")
                        addlogmsg(request.user.username, instance.name, msg)
                        return HttpResponseRedirect(request.get_full_path() + "#xmledit")

                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")
                            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:
                            msg = _("Set VNC password")
                            addlogmsg(request.user.username, instance.name, msg)
                            return HttpResponseRedirect(request.get_full_path() + "#vncsettings")

                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)
                    msg = _("Set VNC keymap")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + "#vncsettings")

                if "set_console_type" in request.POST:
                    console_type = request.POST.get("console_type", "")
                    conn.set_console_type(console_type)
                    msg = _("Set VNC type")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + "#vncsettings")

                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()
                    msg = _("Migrate")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(reverse("instance", args=[compute_id, vname]))

                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)
                    msg = _("Clone")
                    addlogmsg(request.user.username, instance.name, msg)
                    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.username, vname, lib_err.message)

    return render(request, "instance.html", locals())
Example #13
0
def create_instance(request, compute_id, arch, machine):
    """
    :param request:
    :param compute_id:
    :param arch:
    :param machine:
    :return:
    """
    if not request.user.is_superuser:
        return HttpResponseRedirect(reverse('index'))

    conn = None
    error_messages = list()
    storages = list()
    networks = list()
    hypervisors = list()
    firmwares = list()
    meta_prealloc = False
    compute = get_object_or_404(Compute, pk=compute_id)
    flavors = Flavor.objects.filter().order_by('id')

    try:
        conn = wvmCreate(compute.hostname, compute.login, compute.password,
                         compute.type)

        default_firmware = INSTANCE_FIRMWARE_DEFAULT_TYPE
        default_cpu_mode = INSTANCE_CPU_DEFAULT_MODE
        instances = conn.get_instances()
        videos = conn.get_video_models(arch, machine)
        cache_modes = sorted(conn.get_cache_modes().items())
        default_cache = INSTANCE_VOLUME_DEFAULT_CACHE.lower()
        default_io = INSTANCE_VOLUME_DEFAULT_IO.lower()
        default_zeroes = INSTANCE_VOLUME_DEFAULT_DETECT_ZEROES.lower()
        default_discard = INSTANCE_VOLUME_DEFAULT_DISCARD.lower()
        listener_addr = QEMU_CONSOLE_LISTEN_ADDRESSES
        mac_auto = util.randomMAC()
        disk_devices = conn.get_disk_device_types(arch, machine)
        disk_buses = conn.get_disk_bus_types(arch, machine)
        default_bus = INSTANCE_VOLUME_DEFAULT_BUS
        networks = sorted(conn.get_networks())
        nwfilters = conn.get_nwfilters()
        storages = sorted(conn.get_storages(only_actives=True))
        default_graphics = QEMU_CONSOLE_DEFAULT_TYPE

        dom_caps = conn.get_dom_capabilities(arch, machine)
        caps = conn.get_capabilities(arch)

        virtio_support = conn.is_supports_virtio(arch, machine)
        hv_supports_uefi = conn.supports_uefi_xml(dom_caps["loader_enums"])
        # Add BIOS
        label = conn.label_for_firmware_path(arch, None)
        if label: firmwares.append(label)
        # Add UEFI
        loader_path = conn.find_uefi_path_for_arch(arch, dom_caps["loaders"])
        label = conn.label_for_firmware_path(arch, loader_path)
        if label: firmwares.append(label)
        firmwares = list(set(firmwares))

    except libvirtError as lib_err:
        error_messages.append(lib_err)

    if conn:
        if not storages:
            msg = _("You haven't defined any storage pools")
            error_messages.append(msg)
        if not networks:
            msg = _("You haven't defined 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' in request.POST:
                firmware = dict()
                volume_list = list()
                is_disk_created = False
                clone_path = ""
                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 Instance.objects.filter(name__exact=data['name']):
                            messages.warning(
                                request,
                                _("There is an instance with same name. Are you sure?"
                                  ))
                    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)
                                    volume = dict()
                                    volume['path'] = path
                                    volume['type'] = conn.get_volume_type(path)
                                    volume['device'] = 'disk'
                                    if data['virtio']:
                                        volume[
                                            'bus'] = INSTANCE_VOLUME_DEFAULT_BUS
                                    volume_list.append(volume)
                                    is_disk_created = True
                                except libvirtError as lib_err:
                                    error_messages.append(lib_err)
                        elif data['template']:
                            templ_path = conn.get_volume_path(data['template'])
                            dest_vol = conn.get_volume_path(
                                data["name"] + ".img", data['storage'])
                            if dest_vol:
                                error_msg = _(
                                    "Image has already exist. Please check volumes or change instance name"
                                )
                                error_messages.append(error_msg)
                            else:
                                clone_path = conn.clone_from_template(
                                    data['name'],
                                    templ_path,
                                    data['storage'],
                                    metadata=meta_prealloc)
                                volume = dict()
                                volume['path'] = clone_path
                                volume['type'] = conn.get_volume_type(
                                    clone_path)
                                volume['device'] = 'disk'
                                if data['virtio']:
                                    volume['bus'] = INSTANCE_VOLUME_DEFAULT_BUS
                                volume_list.append(volume)
                                is_disk_created = True
                        else:
                            if not data['images']:
                                error_msg = _(
                                    "First you need to create or select an image"
                                )
                                error_messages.append(error_msg)
                            else:
                                for idx, vol in enumerate(
                                        data['images'].split(',')):
                                    try:
                                        path = conn.get_volume_path(vol)
                                        volume = dict()
                                        volume['path'] = path
                                        volume['type'] = conn.get_volume_type(
                                            path)
                                        volume['device'] = request.POST.get(
                                            'device' + str(idx), '')
                                        volume['bus'] = request.POST.get(
                                            'bus' + str(idx), '')
                                        volume_list.append(volume)
                                    except libvirtError as lib_err:
                                        error_messages.append(lib_err)
                        if data['cache_mode'] not in conn.get_cache_modes():
                            error_msg = _("Invalid cache mode")
                            error_messages.append(error_msg)

                        if 'UEFI' in data["firmware"]:
                            firmware["loader"] = data["firmware"].split(
                                ":")[1].strip()
                            firmware["secure"] = 'no'
                            firmware["readonly"] = 'yes'
                            firmware["type"] = 'pflash'
                            if 'secboot' in firmware[
                                    "loader"] and machine != 'q35':
                                messages.warning(
                                    request,
                                    "Changing machine type from '%s' to 'q35' "
                                    "which is required for UEFI secure boot." %
                                    machine)
                                machine = 'q35'
                                firmware["secure"] = 'yes'

                        if not error_messages:
                            uuid = util.randomUUID()
                            try:
                                conn.create_instance(
                                    name=data['name'],
                                    memory=data['memory'],
                                    vcpu=data['vcpu'],
                                    vcpu_mode=data['vcpu_mode'],
                                    uuid=uuid,
                                    arch=arch,
                                    machine=machine,
                                    firmware=firmware,
                                    images=volume_list,
                                    cache_mode=data['cache_mode'],
                                    io_mode=default_io,
                                    discard_mode=default_discard,
                                    detect_zeroes_mode=default_zeroes,
                                    networks=data['networks'],
                                    virtio=data['virtio'],
                                    listen_addr=data["listener_addr"],
                                    nwfilter=data["nwfilter"],
                                    graphics=data["graphics"],
                                    video=data["video"],
                                    console_pass=data["console_pass"],
                                    mac=data['mac'],
                                    qemu_ga=data['qemu_ga'])
                                create_instance = Instance(
                                    compute_id=compute_id,
                                    name=data['name'],
                                    uuid=uuid)
                                create_instance.save()
                                msg = _("Instance is created.")
                                messages.success(request, msg)
                                addlogmsg(request.user.username,
                                          create_instance.name, msg)
                                return HttpResponseRedirect(
                                    reverse('instance',
                                            args=[compute_id, data['name']]))
                            except libvirtError as lib_err:
                                if data['hdd_size'] or len(volume_list) > 0:
                                    if is_disk_created:
                                        for vol in volume_list:
                                            conn.delete_volume(vol['path'])
                                error_messages.append(lib_err)
        conn.close()
    return render(request, 'create_instance_w2.html', locals())
Example #14
0
def nwfilters(request, compute_id):
    """
    :param request:
    :return:
    """

    if not request.user.is_superuser:
        return HttpResponseRedirect(reverse('index'))

    error_messages = []
    nwfilters_all = []
    compute = get_object_or_404(Compute, pk=compute_id)

    try:
        conn = wvmNWFilters(compute.hostname,
                           compute.login,
                           compute.password,
                           compute.type)

        if request.method == 'POST':
            if 'create_nwfilter' in request.POST:
                xml = request.POST.get('nwfilter_xml', '')
                if xml:
                    try:
                        util.etree.fromstring(xml)
                        name = util.get_xml_path(xml, '/filter/@name')
                        uuid = util.get_xml_path(xml, '/filter/uuid')
                    except util.etree.ParseError:
                        name = None

                    for nwf in nwfilters:
                        if name == nwf.name():
                            error_msg = _("A network filter with this name already exists")
                            raise Exception(error_msg)
                        if uuid == nwf.UUIDString():
                            error_msg = _("A network filter with this uuid already exists")
                            raise Exception(error_msg)
                    else:
                        try:
                            msg = _("Creating NWFilter: %s" % name)
                            conn.create_nwfilter(xml)
                            addlogmsg(request.user.username, compute.hostname, msg)
                        except libvirtError as lib_err:
                            error_messages.append(lib_err.message)
                            addlogmsg(request.user.username, compute.hostname, lib_err.message)

            if 'del_nwfilter' in request.POST:
                name = request.POST.get('nwfiltername','')
                msg = _("Deleting NWFilter: %s" % name)
                in_use = False
                nwfilter = conn.get_nwfilter(name)

                is_conn = wvmInstances(compute.hostname, compute.login, compute.password, compute.type)
                instances = is_conn.get_instances()
                for inst in instances:
                #    if in_use: break
                    i_conn = wvmInstance(compute.hostname, compute.login, compute.password, compute.type, inst)
                    dom_filterrefs = i_conn.get_filterrefs()

                    if name in dom_filterrefs:
                        in_use = True
                        msg = _("NWFilter is in use by %s. Cannot be deleted." % inst)
                        error_messages.append(msg)
                        addlogmsg(request.user.username, compute.hostname, msg)
                        i_conn.close()
                        break

                is_conn.close()
                if nwfilter and not in_use:
                    nwfilter.undefine()
                    addlogmsg(request.user.username, compute.hostname, msg)

            if 'cln_nwfilter' in request.POST:

                name = request.POST.get('nwfiltername','')
                cln_name = request.POST.get('cln_name', name + '-clone')

                conn.clone_nwfilter(name,cln_name)
                msg = _("Cloning NWFilter %s as %s" % (name, cln_name))
                addlogmsg(request.user.username, compute.hostname, msg)

        for nwf in conn.get_nwfilters():
            nwfilters_all.append(conn.get_nwfilter_info(nwf))

        conn.close()
    except libvirtError as lib_err:
        error_messages.append(lib_err)
        addlogmsg(request.user.username, compute.hostname, lib_err)
    except Exception as err:
        error_messages.append(err)
        addlogmsg(request.user.username, compute.hostname, err)

    return render(request, 'nwfilters.html', {'error_messages': error_messages,
                                              'nwfilters': nwfilters_all,
                                              'compute': compute})
Example #15
0
def instances(request):
    """
    :param request:
    :return:
    """

    error_messages = []
    all_host_vms = {}
    all_user_vms = {}
    computes = Compute.objects.all().order_by("name")

    def get_userinstances_info(instance):
        info = {}
        uis = UserInstance.objects.filter(instance=instance)
        info['count'] = uis.count()
        if info['count'] > 0:
            info['first_user'] = uis[0]
        else:
            info['first_user'] = None
        return info

    def refresh_instance_database(comp, vm, info):
        instances = Instance.objects.filter(name=vm)
        if instances.count() > 1:
            for i in instances:
                user_instances_count = UserInstance.objects.filter(instance=i).count()
                if user_instances_count == 0:
                    addlogmsg(request.user.username, i.name, _("Deleting due to multiple records."))
                    i.delete()
        
        try:
            check_uuid = Instance.objects.get(compute_id=comp["id"], name=vm)
            if check_uuid.uuid != info['uuid']:
                check_uuid.save()

            all_host_vms[comp["id"],
                         comp["name"],
                         comp["status"],
                         comp["cpu"],
                         comp["mem_size"],
                         comp["mem_perc"]][vm]['is_template'] = check_uuid.is_template
            all_host_vms[comp["id"],
                         comp["name"],
                         comp["status"],
                         comp["cpu"],
                         comp["mem_size"],
                         comp["mem_perc"]][vm]['userinstances'] = get_userinstances_info(check_uuid)
        except Instance.DoesNotExist:
            check_uuid = Instance(compute_id=comp["id"], name=vm, uuid=info['uuid'])
            check_uuid.save()
    
    if not request.user.is_superuser:
        user_instances = UserInstance.objects.filter(user_id=request.user.id)
        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:
            status = connection_manager.host_is_up(comp.type, comp.hostname)
            if status:
                try:
                    conn = wvmHostDetails(comp, comp.login, comp.password, comp.type)
                    comp_node_info = conn.get_node_info()
                    comp_mem = conn.get_memory_usage()
                    comp_instances = conn.get_host_instances(True)

                    if comp_instances:
                        comp_info= {
                            "id": comp.id,
                            "name": comp.name,
                            "status": status,
                            "cpu": comp_node_info[3],
                            "mem_size": comp_node_info[2],
                            "mem_perc": comp_mem['percent']
                        }
                        all_host_vms[comp_info["id"], comp_info["name"], comp_info["status"], comp_info["cpu"],
                                     comp_info["mem_size"], comp_info["mem_perc"]] = comp_instances
                        for vm, info in comp_instances.items():
                            refresh_instance_database(comp_info, vm, info)

                    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.username, instance.name, msg)
                conn.start(name)
                return HttpResponseRedirect(request.get_full_path())

            if 'poweroff' in request.POST:
                msg = _("Power Off")
                addlogmsg(request.user.username, instance.name, msg)
                conn.shutdown(name)
                return HttpResponseRedirect(request.get_full_path())

            if 'powercycle' in request.POST:
                msg = _("Power Cycle")
                conn.force_shutdown(name)
                conn.start(name)
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path())

            if 'getvvfile' in request.POST:
                msg = _("Send console.vv file")
                addlogmsg(request.user.username, instance.name, msg)
                response = HttpResponse(content='', content_type='application/x-virt-viewer', status=200, reason=None, charset='utf-8')
                response.writelines('[virt-viewer]\n')
                response.writelines('type=' + conn.graphics_type(name) + '\n')
                response.writelines('host=' + conn.graphics_listen(name) + '\n')
                response.writelines('port=' + conn.graphics_port(name) + '\n')
                response.writelines('title=' + conn.domain_name(name) + '\n')
                response.writelines('password='******'\n')
                response.writelines('enable-usbredir=1\n')
                response.writelines('disable-effects=all\n')
                response.writelines('secure-attention=ctrl+alt+ins\n')
                response.writelines('release-cursor=ctrl+alt\n')
                response.writelines('fullscreen=1\n')
                response.writelines('delete-this-file=1\n')
                response['Content-Disposition'] = 'attachment; filename="console.vv"'
                return response

            if request.user.is_superuser:

                if 'suspend' in request.POST:
                    msg = _("Suspend")
                    addlogmsg(request.user.username, instance.name, msg)
                    conn.suspend(name)
                    return HttpResponseRedirect(request.get_full_path())

                if 'resume' in request.POST:
                    msg = _("Resume")
                    addlogmsg(request.user.username, instance.name, msg)
                    conn.resume(name)
                    return HttpResponseRedirect(request.get_full_path())

        except libvirtError as lib_err:
            error_messages.append(lib_err)
            addlogmsg(request.user.username, instance.name, lib_err.message)

    view_style = settings.VIEW_INSTANCES_LIST_STYLE

    return render(request, 'instances.html', locals())
Example #16
0
def appsettings(request):
    """
    :param request:
    :return:
    """
    main_css = "wvc-main.min.css"
    sass_dir = AppSettings.objects.get(key="SASS_DIR")
    bootstrap_theme = AppSettings.objects.get(key="BOOTSTRAP_THEME")
    try:
        themes_list = os.listdir(sass_dir.value + "/wvc-theme")
    except FileNotFoundError as err:
        messages.error(request, err)
        addlogmsg(request.user.username, "", err)

    # Bootstrap settings related with filesystems, because of that they are excluded from other settings
    appsettings = AppSettings.objects.exclude(
        description__startswith="Bootstrap").order_by("name")

    if request.method == "POST":
        if "SASS_DIR" in request.POST:
            try:
                sass_dir.value = request.POST.get("SASS_DIR", "")
                sass_dir.save()

                msg = _("SASS directory path is changed. Now: %(dir)s") % {
                    "dir": sass_dir.value
                }
                messages.success(request, msg)
            except Exception as err:
                msg = err
                messages.error(request, msg)

            addlogmsg(request.user.username, "", msg)
            return HttpResponseRedirect(request.get_full_path())

        if "BOOTSTRAP_THEME" in request.POST:
            theme = request.POST.get("BOOTSTRAP_THEME", "")
            scss_var = f"@import '{sass_dir.value}/wvc-theme/{theme}/variables';"
            scss_bootswatch = f"@import '{sass_dir.value}/wvc-theme/{theme}/bootswatch';"
            scss_boot = f"@import '{sass_dir.value}/bootstrap-overrides.scss';"

            try:
                with open(sass_dir.value + "/wvc-main.scss", "w") as main:
                    main.write(scss_var + "\n" + scss_boot + "\n" +
                               scss_bootswatch + "\n")

                css_compressed = sass.compile(
                    string=scss_var + "\n" + scss_boot + "\n" +
                    scss_bootswatch,
                    output_style="compressed",
                )
                with open("static/css/" + main_css, "w") as css:
                    css.write(css_compressed)

                bootstrap_theme.value = theme
                bootstrap_theme.save()

                msg = _("Theme is changed. Now: %(theme)s") % {"theme": theme}
                messages.success(request, msg)
            except Exception as err:
                msg = err
                messages.error(request, msg)

            addlogmsg(request.user.username, "", msg)
            return HttpResponseRedirect(request.get_full_path())

        for setting in appsettings:
            if setting.key in request.POST:
                try:
                    setting.value = request.POST.get(setting.key, "")
                    setting.save()

                    msg = _("%(setting)s is changed. Now: %(value)s") % {
                        "setting": setting.name,
                        "value": setting.value
                    }
                    messages.success(request, msg)
                except Exception as err:
                    msg = err
                    messages.error(request, msg)

                addlogmsg(request.user.username, "", msg)
                return HttpResponseRedirect(request.get_full_path())

    return render(request, "appsettings.html", locals())
Example #17
0
def instance(request, compute_id, vname):
    """
    :param request:
    :return:
    """

    if not request.user.is_authenticated():
        return HttpResponseRedirect(reverse('index'))

    error_messages = []
    messages = []
    compute = get_object_or_404(Compute, pk=compute_id)
    computes = Compute.objects.all()
    computes_count = len(computes)
    publickeys = UserSSHKey.objects.filter(user_id=request.user.id)
    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:
                conn.start()
                msg = _("Power On")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() +
                                            '#poweron')

            if 'powercycle' in request.POST:
                conn.force_shutdown()
                conn.start()
                msg = _("Power Cycle")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() +
                                            '#powercycle')

            if 'poweroff' in request.POST:
                conn.shutdown()
                msg = _("Power Off")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() +
                                            '#poweroff')

            if 'powerforce' in request.POST:
                conn.force_shutdown()
                msg = _("Force Off")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() +
                                            '#powerforce')

            if 'delete' in request.POST:
                if conn.get_status() == 1:
                    conn.force_shutdown()
                if request.POST.get('delete_disk', ''):
                    conn.delete_disk()
                conn.delete()

                instance = Instance.objects.get(compute_id=compute_id,
                                                name=vname)
                instance_name = instance.name
                instance.delete()

                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.delete()
                    except UserInstance.DoesNotExist:
                        pass

                msg = _("Destroy")
                addlogmsg(request.user.username, instance_name, msg)

                return HttpResponseRedirect(reverse('instances'))

            if 'rootpasswd' in request.POST:
                passwd = request.POST.get('passwd', '')
                passwd_hash = crypt.crypt(passwd, '$6$kgPoiREy')
                data = {
                    'action': 'password',
                    'passwd': passwd_hash,
                    'vname': vname
                }

                if conn.get_status() == 5:
                    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    s.connect((compute.hostname, 16510))
                    s.send(json.dumps(data))
                    result = json.loads(s.recv(1024))
                    s.close()
                    msg = _("Reset root password")
                    addlogmsg(request.user.username, instance.name, msg)

                    if result['return'] == 'success':
                        messages.append(msg)
                    else:
                        error_messages.append(msg)
                else:
                    msg = _(
                        "Please shutdow down your instance and then try again")
                    error_messages.append(msg)

            if 'addpublickey' in request.POST:
                sshkeyid = request.POST.get('sshkeyid', '')
                publickey = UserSSHKey.objects.get(id=sshkeyid)
                data = {
                    'action': 'publickey',
                    'key': publickey.keypublic,
                    'vname': vname
                }

                if conn.get_status() == 5:
                    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    s.connect((compute.hostname, 16510))
                    s.send(json.dumps(data))
                    result = json.loads(s.recv(1024))
                    s.close()
                    msg = _("Installed new ssh public key %s" %
                            publickey.keyname)
                    addlogmsg(request.user.username, instance.name, msg)

                    if result['return'] == 'success':
                        messages.append(msg)
                    else:
                        error_messages.append(msg)
                else:
                    msg = _(
                        "Please shutdow down your instance and then try again")
                    error_messages.append(msg)

            if 'resize' in request.POST:
                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)
                msg = _("Resize")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() +
                                            '#resize')

            if 'umount_iso' in request.POST:
                image = request.POST.get('path', '')
                dev = request.POST.get('umount_iso', '')
                conn.umount_iso(dev, image)
                msg = _("Mount media")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#media')

            if 'mount_iso' in request.POST:
                image = request.POST.get('media', '')
                dev = request.POST.get('mount_iso', '')
                conn.mount_iso(dev, image)
                msg = _("Umount media")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#media')

            if 'snapshot' in request.POST:
                name = request.POST.get('name', '')
                conn.create_snapshot(name)
                msg = _("New snapshot")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() +
                                            '#restoresnapshot')

            if 'delete_snapshot' in request.POST:
                snap_name = request.POST.get('name', '')
                conn.snapshot_delete(snap_name)
                msg = _("Delete snapshot")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() +
                                            '#restoresnapshot')

            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)
                msg = _("Revert snapshot")
                addlogmsg(request.user.username, instance.name, msg)

            if request.user.is_superuser:
                if 'suspend' in request.POST:
                    conn.suspend()
                    msg = _("Suspend")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() +
                                                '#resume')

                if 'resume' in request.POST:
                    conn.resume()
                    msg = _("Resume")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() +
                                                '#suspend')

                if 'set_autostart' in request.POST:
                    conn.set_autostart(1)
                    msg = _("Set autostart")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() +
                                                '#autostart')

                if 'unset_autostart' in request.POST:
                    conn.set_autostart(0)
                    msg = _("Unset autostart")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() +
                                                '#autostart')

                if 'change_xml' in request.POST:
                    exit_xml = request.POST.get('inst_xml', '')
                    if exit_xml:
                        conn._defineXML(exit_xml)
                        msg = _("Edit XML")
                        addlogmsg(request.user.username, instance.name, msg)
                        return HttpResponseRedirect(request.get_full_path() +
                                                    '#xmledit')

                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"
                            )
                            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:
                            msg = _("Set VNC password")
                            addlogmsg(request.user.username, instance.name,
                                      msg)
                            return HttpResponseRedirect(
                                request.get_full_path() + '#vncsettings')

                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)
                    msg = _("Set VNC keymap")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() +
                                                '#vncsettings')

                if 'set_console_type' in request.POST:
                    console_type = request.POST.get('console_type', '')
                    conn.set_console_type(console_type)
                    msg = _("Set VNC type")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() +
                                                '#vncsettings')

                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()
                    msg = _("Migrate")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(
                        reverse('instance', args=[compute_id, vname]))

                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)
                    msg = _("Clone")
                    addlogmsg(request.user.username, instance.name, msg)
                    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.username, vname, lib_err.message)

    return render(request, 'instance.html', locals())
Example #18
0
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.filter(user_id=request.user.id)
        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)
                    if conn.get_host_instances():
                        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.username, instance.name, msg)
                conn.start(name)
                return HttpResponseRedirect(request.get_full_path())

            if 'poweroff' in request.POST:
                msg = _("Power Off")
                addlogmsg(request.user.username, instance.name, msg)
                conn.shutdown(name)
                return HttpResponseRedirect(request.get_full_path())

            if 'powercycle' in request.POST:
                msg = _("Power Cycle")
                conn.force_shutdown(name)
                conn.start(name)
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path())

            if request.user.is_superuser:

                if 'suspend' in request.POST:
                    msg = _("Suspend")
                    addlogmsg(request.user.username, instance.name, msg)
                    conn.suspend(name)
                    return HttpResponseRedirect(request.get_full_path())

                if 'resume' in request.POST:
                    msg = _("Resume")
                    addlogmsg(request.user.username, instance.name, msg)
                    conn.resume(name)
                    return HttpResponseRedirect(request.get_full_path())

        except libvirtError as lib_err:
            error_messages.append(lib_err)
            addlogmsg(request.user.username, instance.name, lib_err.message)

    return render(request, 'instances.html', locals())
Example #19
0
def instance(request, compute_id, vname):
    """
    :param request:
    :return:
    """

    error_messages = []
    messages = []
    compute = get_object_or_404(Compute, pk=compute_id)
    computes = Compute.objects.all().order_by('name')
    computes_count = computes.count()
    users = User.objects.all().order_by('username')
    publickeys = UserSSHKey.objects.filter(user_id=request.user.id)
    keymaps = settings.QEMU_KEYMAPS
    console_types = settings.QEMU_CONSOLE_TYPES
    console_listen_addresses = settings.QEMU_CONSOLE_LISTEN_ADDRESSES
    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, vname=''):
        clone_disk = []
        for disk in disks:
            if disk['image'] is None:
                continue
            if disk['image'].count("-") and disk['image'].rsplit(
                    "-", 1)[0] == vname:
                name, suffix = disk['image'].rsplit("-", 1)
                image = name + "-clone" + "-" + suffix
            elif 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

    def filesizefstr(size_str):
        if size_str == '':
            return 0
        size_str = size_str.encode('ascii',
                                   'ignore').upper().translate(None, " B")
        if 'K' == size_str[-1]:
            return long(float(size_str[:-1])) << 10
        elif 'M' == size_str[-1]:
            return long(float(size_str[:-1])) << 20
        elif 'G' == size_str[-1]:
            return long(float(size_str[:-1])) << 30
        elif 'T' == size_str[-1]:
            return long(float(size_str[:-1])) << 40
        elif 'P' == size_str[-1]:
            return long(float(size_str[:-1])) << 50
        else:
            return long(float(size_str))

    def get_clone_free_names(size=10):
        prefix = settings.CLONE_INSTANCE_DEFAULT_PREFIX
        free_names = []
        existing_names = [
            i.name for i in Instance.objects.filter(name__startswith=prefix)
        ]
        index = 1
        while len(free_names) < size:
            new_name = prefix + str(index)
            if new_name not in existing_names:
                free_names.append(new_name)
            index += 1
        return free_names

    def check_user_quota(instance, cpu, memory, disk_size):
        user_instances = UserInstance.objects.filter(
            user_id=request.user.id, instance__is_template=False)
        instance += user_instances.count()
        for usr_inst in user_instances:
            if connection_manager.host_is_up(
                    usr_inst.instance.compute.type,
                    usr_inst.instance.compute.hostname):
                conn = wvmInstance(usr_inst.instance.compute,
                                   usr_inst.instance.compute.login,
                                   usr_inst.instance.compute.password,
                                   usr_inst.instance.compute.type,
                                   usr_inst.instance.name)
                cpu += int(conn.get_vcpu())
                memory += int(conn.get_memory())
                for disk in conn.get_disk_device():
                    if disk['size']:
                        disk_size += int(disk['size']) >> 30

        ua = request.user.userattributes
        msg = ""
        if ua.max_instances > 0 and instance > ua.max_instances:
            msg = "instance"
            if settings.QUOTA_DEBUG:
                msg += " (%s > %s)" % (instance, ua.max_instances)
        if ua.max_cpus > 0 and cpu > ua.max_cpus:
            msg = "cpu"
            if settings.QUOTA_DEBUG:
                msg += " (%s > %s)" % (cpu, ua.max_cpus)
        if ua.max_memory > 0 and memory > ua.max_memory:
            msg = "memory"
            if settings.QUOTA_DEBUG:
                msg += " (%s > %s)" % (memory, ua.max_memory)
        if ua.max_disk_size > 0 and disk_size > ua.max_disk_size:
            msg = "disk"
            if settings.QUOTA_DEBUG:
                msg += " (%s > %s)" % (disk_size, ua.max_disk_size)
        return msg

    def get_new_disk_dev(disks, bus):
        if bus == "virtio":
            dev_base = "vd"
        else:
            dev_base = "sd"
        existing_devs = [disk['dev'] for disk in disks]
        for l in string.lowercase:
            dev = dev_base + l
            if dev not in existing_devs:
                return dev
        raise Exception(_('None available device name'))

    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()
        title = conn.get_title()
        description = conn.get_description()
        disks = conn.get_disk_device()
        media = conn.get_media_device()
        networks = conn.get_net_device()
        if len(media) != 0:
            media_iso = sorted(conn.get_iso_media())
        else:
            media_iso = []
        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,
                           key=lambda k: k['date'])
        inst_xml = conn._XMLDesc(VIR_DOMAIN_XML_SECURE)
        has_managed_save_image = conn.get_managed_save_image()
        clone_disks = show_clone_disk(disks, vname)
        console_passwd = conn.get_console_passwd()
        clone_free_names = get_clone_free_names()
        user_quota_msg = check_user_quota(0, 0, 0, 0)
        storages = sorted(conn.get_storages())
        cache_modes = sorted(conn.get_cache_modes().items())
        default_cache = settings.INSTANCE_VOLUME_DEFAULT_CACHE
        default_format = settings.INSTANCE_VOLUME_DEFAULT_FORMAT
        formats = conn.get_image_formats()
        busses = conn.get_busses()
        default_bus = settings.INSTANCE_VOLUME_DEFAULT_BUS
        show_access_root_password = settings.SHOW_ACCESS_ROOT_PASSWORD
        show_access_ssh_keys = settings.SHOW_ACCESS_SSH_KEYS

        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()

        userinstances = UserInstance.objects.filter(
            instance=instance).order_by('user__username')

        if request.method == 'POST':
            if 'poweron' in request.POST:
                conn.start()
                msg = _("Power On")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() +
                                            '#poweron')

            if 'powercycle' in request.POST:
                conn.force_shutdown()
                conn.start()
                msg = _("Power Cycle")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() +
                                            '#powercycle')

            if 'poweroff' in request.POST:
                conn.shutdown()
                msg = _("Power Off")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() +
                                            '#poweroff')

            if 'powerforce' in request.POST:
                conn.force_shutdown()
                msg = _("Force Off")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() +
                                            '#powerforce')

            if 'delete' in request.POST and (request.user.is_superuser
                                             or userinstace.is_delete):
                if conn.get_status() == 1:
                    conn.force_shutdown()
                if request.POST.get('delete_disk', ''):
                    for snap in snapshots:
                        conn.snapshot_delete(snap['name'])
                    conn.delete_disk()
                conn.delete()

                instance = Instance.objects.get(compute_id=compute_id,
                                                name=vname)
                instance_name = instance.name
                instance.delete()

                try:
                    del_userinstance = UserInstance.objects.filter(
                        instance__compute_id=compute_id, instance__name=vname)
                    del_userinstance.delete()
                except UserInstance.DoesNotExist:
                    pass

                msg = _("Destroy")
                addlogmsg(request.user.username, instance_name, msg)

                return HttpResponseRedirect(reverse('instances'))

            if 'rootpasswd' in request.POST:
                passwd = request.POST.get('passwd', '')
                passwd_hash = crypt.crypt(passwd, '$6$kgPoiREy')
                data = {
                    'action': 'password',
                    'passwd': passwd_hash,
                    'vname': vname
                }

                if conn.get_status() == 5:
                    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    s.connect((compute.hostname, 16510))
                    s.send(json.dumps(data))
                    result = json.loads(s.recv(1024))
                    s.close()
                    msg = _("Reset root password")
                    addlogmsg(request.user.username, instance.name, msg)

                    if result['return'] == 'success':
                        messages.append(msg)
                    else:
                        error_messages.append(msg)
                else:
                    msg = _(
                        "Please shutdow down your instance and then try again")
                    error_messages.append(msg)

            if 'addpublickey' in request.POST:
                sshkeyid = request.POST.get('sshkeyid', '')
                publickey = UserSSHKey.objects.get(id=sshkeyid)
                data = {
                    'action': 'publickey',
                    'key': publickey.keypublic,
                    'vname': vname
                }

                if conn.get_status() == 5:
                    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    s.connect((compute.hostname, 16510))
                    s.send(json.dumps(data))
                    result = json.loads(s.recv(1024))
                    s.close()
                    msg = _("Installed new ssh public key %s" %
                            publickey.keyname)
                    addlogmsg(request.user.username, instance.name, msg)

                    if result['return'] == 'success':
                        messages.append(msg)
                    else:
                        error_messages.append(msg)
                else:
                    msg = _(
                        "Please shutdow down your instance and then try again")
                    error_messages.append(msg)

            if 'resize' in request.POST and (request.user.is_superuser
                                             or request.user.is_staff
                                             or userinstace.is_change):
                new_vcpu = request.POST.get('vcpu', '')
                new_cur_vcpu = request.POST.get('cur_vcpu', '')
                new_memory = request.POST.get('memory', '')
                new_memory_custom = request.POST.get('memory_custom', '')
                if new_memory_custom:
                    new_memory = new_memory_custom
                new_cur_memory = request.POST.get('cur_memory', '')
                new_cur_memory_custom = request.POST.get(
                    'cur_memory_custom', '')
                if new_cur_memory_custom:
                    new_cur_memory = new_cur_memory_custom
                disks_new = []
                for disk in disks:
                    input_disk_size = filesizefstr(
                        request.POST.get('disk_size_' + disk['dev'], ''))
                    if input_disk_size > disk['size'] + (64 << 20):
                        disk['size_new'] = input_disk_size
                        disks_new.append(disk)
                disk_sum = sum([disk['size'] >> 30 for disk in disks_new])
                disk_new_sum = sum(
                    [disk['size_new'] >> 30 for disk in disks_new])
                quota_msg = check_user_quota(0,
                                             int(new_vcpu) - vcpu,
                                             int(new_memory) - memory,
                                             disk_new_sum - disk_sum)
                if not request.user.is_superuser and quota_msg:
                    msg = _("User %s quota reached, cannot resize '%s'!" %
                            (quota_msg, instance.name))
                    error_messages.append(msg)
                else:
                    cur_memory = new_cur_memory
                    memory = new_memory
                    cur_vcpu = new_cur_vcpu
                    vcpu = new_vcpu
                    conn.resize(cur_memory, memory, cur_vcpu, vcpu, disks_new)
                    msg = _("Resize")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() +
                                                '#resize')

            if 'addvolume' in request.POST and (request.user.is_superuser
                                                or userinstace.is_change):
                connCreate = wvmCreate(compute.hostname, compute.login,
                                       compute.password, compute.type)
                storage = request.POST.get('storage', '')
                name = request.POST.get('name', '')
                extension = request.POST.get('extension', '')
                format = request.POST.get('format', '')
                size = request.POST.get('size', 0)
                meta_prealloc = request.POST.get('meta_prealloc', False)
                bus = request.POST.get('bus', '')
                cache = request.POST.get('cache', '')
                target = get_new_disk_dev(disks, bus)

                path = connCreate.create_volume(storage, name, size, format,
                                                meta_prealloc, extension)
                conn.attach_disk(path,
                                 target,
                                 subdriver=format,
                                 cache=cache,
                                 targetbus=bus)
                msg = _('Attach new disk')
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() +
                                            '#resize')

            if 'umount_iso' in request.POST:
                image = request.POST.get('path', '')
                dev = request.POST.get('umount_iso', '')
                conn.umount_iso(dev, image)
                msg = _("Mount media")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#media')

            if 'mount_iso' in request.POST:
                image = request.POST.get('media', '')
                dev = request.POST.get('mount_iso', '')
                conn.mount_iso(dev, image)
                msg = _("Umount media")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#media')

            if 'snapshot' in request.POST:
                name = request.POST.get('name', '')
                conn.create_snapshot(name)
                msg = _("New snapshot")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() +
                                            '#restoresnapshot')

            if 'delete_snapshot' in request.POST:
                snap_name = request.POST.get('name', '')
                conn.snapshot_delete(snap_name)
                msg = _("Delete snapshot")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() +
                                            '#restoresnapshot')

            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)
                msg = _("Revert snapshot")
                addlogmsg(request.user.username, instance.name, msg)

            if request.user.is_superuser:
                if 'suspend' in request.POST:
                    conn.suspend()
                    msg = _("Suspend")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() +
                                                '#resume')

                if 'resume' in request.POST:
                    conn.resume()
                    msg = _("Resume")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() +
                                                '#suspend')

                if 'set_autostart' in request.POST:
                    conn.set_autostart(1)
                    msg = _("Set autostart")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() +
                                                '#autostart')

                if 'unset_autostart' in request.POST:
                    conn.set_autostart(0)
                    msg = _("Unset autostart")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() +
                                                '#autostart')

                if 'change_xml' in request.POST:
                    exit_xml = request.POST.get('inst_xml', '')
                    if exit_xml:
                        conn._defineXML(exit_xml)
                        msg = _("Edit XML")
                        addlogmsg(request.user.username, instance.name, msg)
                        return HttpResponseRedirect(request.get_full_path() +
                                                    '#xmledit')

            if request.user.is_superuser or userinstace.is_vnc:
                if 'set_console_passwd' in request.POST:
                    if request.POST.get('auto_pass', ''):
                        passwd = randomPasswd()
                    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:
                            msg = _("Set VNC password")
                            addlogmsg(request.user.username, instance.name,
                                      msg)
                            return HttpResponseRedirect(
                                request.get_full_path() + '#vncsettings')

                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)
                    msg = _("Set VNC keymap")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() +
                                                '#vncsettings')

                if 'set_console_type' in request.POST:
                    console_type = request.POST.get('console_type', '')
                    conn.set_console_type(console_type)
                    msg = _("Set VNC type")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() +
                                                '#vncsettings')

                if 'set_console_listen_address' in request.POST:
                    console_type = request.POST.get('console_listen_address',
                                                    '')
                    conn.set_console_listen_addr(console_type)
                    msg = _("Set VNC listen address")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() +
                                                '#vncsettings')

            if request.user.is_superuser:
                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)
                    offline = request.POST.get('offline_migrate', 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,
                                        offline)
                    instance.compute = new_compute
                    instance.save()
                    conn_migrate.close()
                    if autostart:
                        conn_new = wvmInstance(new_compute.hostname,
                                               new_compute.login,
                                               new_compute.password,
                                               new_compute.type, vname)
                        conn_new.set_autostart(1)
                        conn_new.close()
                    msg = _("Migrate to %s" % new_compute.hostname)
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(
                        reverse('instance', args=[compute_id, vname]))

                if 'change_network' in request.POST:
                    network_data = {}

                    for post in request.POST:
                        if post.startswith('net-'):
                            network_data[post] = request.POST.get(post, '')

                    conn.change_network(network_data)
                    msg = _("Edit network")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() +
                                                '#network')

                if 'add_owner' in request.POST:
                    user_id = int(request.POST.get('user_id', ''))

                    if settings.ALLOW_INSTANCE_MULTIPLE_OWNER:
                        check_inst = UserInstance.objects.filter(
                            instance=instance, user_id=user_id)
                    else:
                        check_inst = UserInstance.objects.filter(
                            instance=instance)

                    if check_inst:
                        msg = _("Owner already added")
                        error_messages.append(msg)
                    else:
                        add_user_inst = UserInstance(instance=instance,
                                                     user_id=user_id)
                        add_user_inst.save()
                        msg = _("Added owner %d" % user_id)
                        addlogmsg(request.user.username, instance.name, msg)
                        return HttpResponseRedirect(request.get_full_path() +
                                                    '#users')

                if 'del_owner' in request.POST:
                    userinstance_id = int(request.POST.get('userinstance', ''))
                    userinstance = UserInstance.objects.get(pk=userinstance_id)
                    userinstance.delete()
                    msg = _("Deleted owner %d" % userinstance_id)
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() +
                                                '#users')

            if request.user.is_superuser or request.user.userattributes.can_clone_instances:
                if 'clone' in request.POST:
                    clone_data = {}
                    clone_data['name'] = request.POST.get('name', '')

                    disk_sum = sum([disk['size'] >> 30 for disk in disks])
                    quota_msg = check_user_quota(1, vcpu, memory, disk_sum)
                    check_instance = Instance.objects.filter(
                        name=clone_data['name'])

                    for post in request.POST:
                        clone_data[post] = request.POST.get(post, '').strip()

                    if not request.user.is_superuser and quota_msg:
                        msg = _("User %s quota reached, cannot create '%s'!" %
                                (quota_msg, clone_data['name']))
                        error_messages.append(msg)
                    elif check_instance:
                        msg = _("Instance '%s' already exists!" %
                                clone_data['name'])
                        error_messages.append(msg)
                    elif not re.match(r'^[a-zA-Z0-9-]+$', clone_data['name']):
                        msg = _(
                            "Instance name '%s' contains invalid characters!" %
                            clone_data['name'])
                        error_messages.append(msg)
                    elif not re.match(r'^([0-9A-F]{2})(\:?[0-9A-F]{2}){5}$',
                                      clone_data['clone-net-mac-0'],
                                      re.IGNORECASE):
                        msg = _("Instance mac '%s' invalid format!" %
                                clone_data['clone-net-mac-0'])
                        error_messages.append(msg)
                    else:
                        new_uuid = conn.clone_instance(clone_data)
                        new_instance = Instance(compute_id=compute_id,
                                                name=clone_data['name'],
                                                uuid=new_uuid)
                        new_instance.save()
                        userinstance = UserInstance(
                            instance_id=new_instance.id,
                            user_id=request.user.id,
                            is_delete=True)
                        userinstance.save()

                        msg = _("Clone of '%s'" % instance.name)
                        addlogmsg(request.user.username, new_instance.name,
                                  msg)
                        return HttpResponseRedirect(
                            reverse('instance',
                                    args=[compute_id, clone_data['name']]))

                if 'change_options' in request.POST:
                    instance.is_template = request.POST.get(
                        'is_template', False)
                    instance.save()

                    options = {}
                    for post in request.POST:
                        if post in ['title', 'description']:
                            options[post] = request.POST.get(post, '')
                    conn.set_options(options)

                    msg = _("Edit options")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() +
                                                '#options')

        conn.close()

    except libvirtError as lib_err:
        error_messages.append(lib_err.message)
        addlogmsg(request.user.username, vname, lib_err.message)

    return render(request, 'instance.html', locals())
Example #20
0
def instance(request, compute_id, vname):
    """
    :param request:
    :return:
    """

    if not request.user.is_authenticated():
        return HttpResponseRedirect(reverse('index'))

    error_messages = []
    messages = []
    compute = get_object_or_404(Compute, pk=compute_id)
    computes = Compute.objects.all()
    computes_count = len(computes)
    publickeys = UserSSHKey.objects.filter(user_id=request.user.id)
    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:
                conn.start()
                msg = _("Power On")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#poweron')

            if 'powercycle' in request.POST:
                conn.force_shutdown()
                conn.start()
                msg = _("Power Cycle")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#powercycle')

            if 'poweroff' in request.POST:
                conn.shutdown()
                msg = _("Power Off")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#poweroff')

            if 'powerforce' in request.POST:
                conn.force_shutdown()
                msg = _("Force Off")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#powerforce')

            if 'delete' in request.POST:
                if conn.get_status() == 1:
                    conn.force_shutdown()
                if request.POST.get('delete_disk', ''):
                    conn.delete_disk()
                conn.delete()

                instance = Instance.objects.get(compute_id=compute_id, name=vname)
                instance_name = instance.name
                instance.delete()

                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.delete()
                    except UserInstance.DoesNotExist:
                        pass

                msg = _("Destroy")
                addlogmsg(request.user.username, instance_name, msg)

                return HttpResponseRedirect(reverse('instances'))

            if 'rootpasswd' in request.POST:
                passwd = request.POST.get('passwd', '')
                passwd_hash = crypt.crypt(passwd, '$6$kgPoiREy')
                data = {'action': 'password', 'passwd': passwd_hash, 'vname': vname}

                if conn.get_status() == 5:
                    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    s.connect((compute.hostname, 16510))
                    s.send(json.dumps(data))
                    result = json.loads(s.recv(1024))
                    s.close()
                    msg = _("Reset root password")
                    addlogmsg(request.user.username, instance.name, msg)

                    if result['return'] == 'success':
                        messages.append(msg)
                    else:
                        error_messages.append(msg)
                else:
                    msg = _("Please shutdow down your instance and then try again")
                    error_messages.append(msg)

            if 'addpublickey' in request.POST:
                sshkeyid = request.POST.get('sshkeyid', '')
                publickey = UserSSHKey.objects.get(id=sshkeyid)
                data = {'action': 'publickey', 'key': publickey.keypublic, 'vname': vname}

                if conn.get_status() == 5:
                    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    s.connect((compute.hostname, 16510))
                    s.send(json.dumps(data))
                    result = json.loads(s.recv(1024))
                    s.close()
                    msg = _("Installed new ssh public key %s" % publickey.keyname)
                    addlogmsg(request.user.username, instance.name, msg)

                    if result['return'] == 'success':
                        messages.append(msg)
                    else:
                        error_messages.append(msg)
                else:
                    msg = _("Please shutdow down your instance and then try again")
                    error_messages.append(msg)

            if 'resize' in request.POST:
                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)
                msg = _("Resize")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#resize')

            if 'umount_iso' in request.POST:
                image = request.POST.get('path', '')
                dev = request.POST.get('umount_iso', '')
                conn.umount_iso(dev, image)
                msg = _("Mount media")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#media')

            if 'mount_iso' in request.POST:
                image = request.POST.get('media', '')
                dev = request.POST.get('mount_iso', '')
                conn.mount_iso(dev, image)
                msg = _("Umount media")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#media')

            if 'snapshot' in request.POST:
                name = request.POST.get('name', '')
                conn.create_snapshot(name)
                msg = _("New snapshot")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#restoresnapshot')

            if 'delete_snapshot' in request.POST:
                snap_name = request.POST.get('name', '')
                conn.snapshot_delete(snap_name)
                msg = _("Delete snapshot")
                addlogmsg(request.user.username, instance.name, msg)
                return HttpResponseRedirect(request.get_full_path() + '#restoresnapshot')

            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)
                msg = _("Revert snapshot")
                addlogmsg(request.user.username, instance.name, msg)

            if request.user.is_superuser:
                if 'suspend' in request.POST:
                    conn.suspend()
                    msg = _("Suspend")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#resume')

                if 'resume' in request.POST:
                    conn.resume()
                    msg = _("Resume")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#suspend')

                if 'set_autostart' in request.POST:
                    conn.set_autostart(1)
                    msg = _("Set autostart")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#autostart')

                if 'unset_autostart' in request.POST:
                    conn.set_autostart(0)
                    msg = _("Unset autostart")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#autostart')

                if 'change_xml' in request.POST:
                    exit_xml = request.POST.get('inst_xml', '')
                    if exit_xml:
                        conn._defineXML(exit_xml)
                        msg = _("Edit XML")
                        addlogmsg(request.user.username, instance.name, msg)
                        return HttpResponseRedirect(request.get_full_path() + '#xmledit')

                if 'set_console_passwd' in request.POST:
                    if request.POST.get('auto_pass', ''):
                        passwd = randomPasswd()
                    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:
                            msg = _("Set VNC password")
                            addlogmsg(request.user.username, instance.name, msg)
                            return HttpResponseRedirect(request.get_full_path() + '#vncsettings')

                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)
                    msg = _("Set VNC keymap")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#vncsettings')

                if 'set_console_type' in request.POST:
                    console_type = request.POST.get('console_type', '')
                    conn.set_console_type(console_type)
                    msg = _("Set VNC type")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(request.get_full_path() + '#vncsettings')

                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()
                    msg = _("Migrate")
                    addlogmsg(request.user.username, instance.name, msg)
                    return HttpResponseRedirect(reverse('instance', args=[compute_id, vname]))

                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)
                    msg = _("Clone")
                    addlogmsg(request.user.username, instance.name, msg)
                    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.username, vname, lib_err.message)

    return render(request, 'instance.html', locals())
Example #21
0
def nwfilters(request, compute_id):
    """
    :param request:
    :param compute_id:
    :return:
    """

    nwfilters_all = []
    compute = get_object_or_404(Compute, pk=compute_id)

    try:
        conn = wvmNWFilters(compute.hostname, compute.login, compute.password,
                            compute.type)

        for nwf in conn.get_nwfilters():
            nwfilters_all.append(conn.get_nwfilter_info(nwf))

        if request.method == "POST":
            if "create_nwfilter" in request.POST:
                xml = request.POST.get("nwfilter_xml", "")
                if xml:
                    try:
                        util.etree.fromstring(xml)
                        name = util.get_xml_path(xml, "/filter/@name")
                        uuid = util.get_xml_path(xml, "/filter/uuid")
                    except util.etree.ParseError:
                        name = None

                    for nwf in nwfilters_all:
                        if name == nwf["name"]:
                            error_msg = _(
                                "A network filter with this name already exists"
                            )
                            raise Exception(error_msg)
                        if uuid == nwf["uuid"]:
                            error_msg = _(
                                "A network filter with this UUID already exists"
                            )
                            raise Exception(error_msg)
                    else:
                        try:
                            msg = _("%(filter)s network filter is created") % {
                                "filter": name
                            }
                            conn.create_nwfilter(xml)
                            addlogmsg(request.user.username, compute.hostname,
                                      msg)
                        except libvirtError as lib_err:
                            messages.error(request, lib_err)
                            addlogmsg(request.user.username, compute.hostname,
                                      lib_err)

            if "del_nwfilter" in request.POST:
                name = request.POST.get("nwfiltername", "")
                msg = _("%(filter)s network filter is deleted") % {
                    "filter": name
                }
                in_use = False
                nwfilter = conn.get_nwfilter(name)

                is_conn = wvmInstances(compute.hostname, compute.login,
                                       compute.password, compute.type)
                instances = is_conn.get_instances()
                for inst in instances:
                    i_conn = wvmInstance(compute.hostname, compute.login,
                                         compute.password, compute.type, inst)
                    dom_filterrefs = i_conn.get_filterrefs()

                    if name in dom_filterrefs:
                        in_use = True
                        msg = _(
                            "NWFilter is in use by %(instance)s. Cannot be deleted."
                        ) % {
                            "instance": inst
                        }
                        messages.error(request, msg)
                        addlogmsg(request.user.username, compute.hostname, msg)
                        i_conn.close()
                        break

                is_conn.close()
                if nwfilter and not in_use:
                    nwfilter.undefine()
                    addlogmsg(request.user.username, compute.hostname, msg)

            if "cln_nwfilter" in request.POST:

                name = request.POST.get("nwfiltername", "")
                cln_name = request.POST.get("cln_name", name + "-clone")

                conn.clone_nwfilter(name, cln_name)
                msg = _("Cloning NWFilter %(name)s as %(clone)s") % {
                    "name": name,
                    "clone": cln_name
                }
                addlogmsg(request.user.username, compute.hostname, msg)

        conn.close()
    except libvirtError as lib_err:
        messages.error(request, lib_err)
        addlogmsg(request.user.username, compute.hostname, lib_err)
    except Exception as err:
        messages.error(request, err)
        addlogmsg(request.user.username, compute.hostname, err)

    return render(
        request,
        "nwfilters.html",
        {
            "nwfilters": nwfilters_all,
            "compute": compute,
        },
    )
Example #22
0
def create_instance(request, compute_id):
    """
    :param request:
    :return:
    """

    if not request.user.is_superuser:
        return HttpResponseRedirect(reverse('index'))

    conn = None
    error_messages = []
    storages = []
    networks = []
    meta_prealloc = False
    compute = get_object_or_404(Compute, pk=compute_id)
    flavors = Flavor.objects.filter().order_by('id')

    try:
        conn = wvmCreate(compute.hostname,
                         compute.login,
                         compute.password,
                         compute.type)

        storages = sorted(conn.get_storages(only_actives=True))
        networks = sorted(conn.get_networks())
        nwfilters = conn.get_nwfilters()
        instances = conn.get_instances()
        videos = conn.get_video()
        cache_modes = sorted(conn.get_cache_modes().items())
        default_cache = INSTANCE_VOLUME_DEFAULT_CACHE
        listener_addr = QEMU_CONSOLE_LISTEN_ADDRESSES
        mac_auto = util.randomMAC()
        disk_devices = conn.get_disk_device_types()
        disk_buses = conn.get_disk_bus_types()
        default_bus = INSTANCE_VOLUME_DEFAULT_BUS
    except libvirtError as lib_err:
        error_messages.append(lib_err)

    if conn:
        if not storages:
            msg = _("You haven't defined any storage pools")
            error_messages.append(msg)
        if not networks:
            msg = _("You haven't defined 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('dom_xml', '')
                try:
                    name = util.get_xml_path(xml, '/domain/name')
                except util.etree.Error as err:
                    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=[compute_id, name]))
                    except libvirtError as lib_err:
                        error_messages.append(lib_err.message)
            if 'create' in request.POST:
                volume_list = []

                clone_path = ""
                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 Instance.objects.filter(name__exact=data['name']):
                            messages.warning(request,_("There is an instance with same name. Are you sure?"))
                    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)
                                    volume = dict()
                                    volume['path'] = path
                                    volume['type'] = conn.get_volume_type(path)
                                    volume['device'] = 'disk'
                                    volume['bus'] = 'virtio'
                                    volume_list.append(volume)
                                except libvirtError as lib_err:
                                    error_messages.append(lib_err.message)
                        elif data['template']:
                            templ_path = conn.get_volume_path(data['template'])
                            dest_vol = conn.get_volume_path(data["name"] + ".img", data['storage'])
                            if dest_vol:
                                error_msg = _("Image has already exist. Please check volumes or change instance name")
                                error_messages.append(error_msg)
                            else:
                                clone_path = conn.clone_from_template(data['name'], templ_path, data['storage'], metadata=meta_prealloc)
                                volume = dict()
                                volume['path'] = clone_path
                                volume['type'] = conn.get_volume_type(clone_path)
                                volume['device'] = 'disk'
                                volume['bus'] = 'virtio'
                                volume_list.append(volume)
                        else:
                            if not data['images']:
                                error_msg = _("First you need to create or select an image")
                                error_messages.append(error_msg)
                            else:
                                for idx, vol in enumerate(data['images'].split(',')):
                                    try:

                                        path = conn.get_volume_path(vol)
                                        volume = dict()
                                        volume['path'] = path
                                        volume['type'] = conn.get_volume_type(path)
                                        volume['device'] = request.POST.get('device' + str(idx), '')
                                        volume['bus'] = request.POST.get('bus' + str(idx), '')
                                        volume_list.append(volume)
                                    except libvirtError as lib_err:
                                        error_messages.append(lib_err.message)
                        if data['cache_mode'] not in conn.get_cache_modes():
                            error_msg = _("Invalid cache mode")
                            error_messages.append(error_msg)
                        if not error_messages:
                            uuid = util.randomUUID()
                            try:
                                conn.create_instance(data['name'], data['memory'], data['vcpu'], data['host_model'],
                                                     uuid, volume_list, data['cache_mode'], data['networks'], data['virtio'],
                                                     data["listener_addr"], data["nwfilter"], data["video"], data["console_pass"],
                                                     data['mac'], data['qemu_ga'])
                                create_instance = Instance(compute_id=compute_id, name=data['name'], uuid=uuid)
                                create_instance.save()
                                msg = _("Instance is created.")
                                messages.success(request, msg)
                                addlogmsg(request.user.username, create_instance.name, msg)
                                return HttpResponseRedirect(reverse('instance', args=[compute_id, data['name']]))
                            except libvirtError as lib_err:
                                if data['hdd_size'] or volume_list.count() > 0:
                                    for vol in volume_list:
                                        conn.delete_volume(vol['path'])
                                error_messages.append(lib_err)
        conn.close()
    return render(request, 'create_instance.html', locals())