def create_instance(self, name, memory, vcpu, vcpu_mode, uuid, arch, machine, firmware, images, cache_mode, networks, nwfilter, graphics, virtio, listen_addr, video="vga", console_pass="******", mac=None, qemu_ga=False): """ Create VM function """ caps = self.get_capabilities(arch) dom_caps = self.get_dom_capabilities(arch, machine) memory = int(memory) * 1024 #hypervisor_type = 'kvm' if self.is_kvm_supported() else 'qemu' xml = """ <domain type='%s'> <name>%s</name> <description>None</description> <uuid>%s</uuid> <memory unit='KiB'>%s</memory> <vcpu>%s</vcpu>""" % (dom_caps["domain"], name, uuid, memory, vcpu) if dom_caps["os_support"] == 'yes': xml += """<os> <type arch='%s' machine='%s'>%s</type>""" % ( arch, machine, caps["os_type"]) xml += """ <boot dev='hd'/> <boot dev='cdrom'/> <bootmenu enable='yes'/>""" if 'UEFI' in firmware: xml += """<loader readonly='yes' type='pflash'>%s</loader>""" % firmware.split( ":")[1].strip() xml += """</os>""" if caps["features"]: xml += """<features>""" if 'acpi' in caps["features"]: xml += """<acpi/>""" if 'apic' in caps["features"]: xml += """<apic/>""" if 'pae' in caps["features"]: xml += """<pae/>""" xml += """</features>""" if vcpu_mode == "host-model": xml += """<cpu mode='host-model'/>""" elif vcpu_mode == "host-passthrough": xml += """<cpu mode='host-passthrough'/>""" elif vcpu_mode == "": pass else: xml += """<cpu mode='custom' match='exact' check='none'> <model fallback='allow'>{}</model> </cpu>""".format(vcpu_mode) xml += """ <clock offset="utc"/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>restart</on_crash> """ xml += """<devices>""" vd_disk_letters = list(string.lowercase) fd_disk_letters = list(string.lowercase) hd_disk_letters = list(string.lowercase) sd_disk_letters = list(string.lowercase) add_cd = True for volume in images: stg = self.get_storage_by_vol_path(volume['path']) stg_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type") if volume['device'] == 'cdrom': add_cd = False if stg_type == 'rbd': ceph_user, secret_uuid, ceph_hosts = get_rbd_storage_data(stg) xml += """<disk type='network' device='disk'> <driver name='qemu' type='%s' cache='%s' %s />""" % ( volume['type'], cache_mode, OPTS.get("network", '')) xml += """ <auth username='******'> <secret type='ceph' uuid='%s'/> </auth> <source protocol='rbd' name='%s'>""" % ( ceph_user, secret_uuid, volume['path']) if isinstance(ceph_hosts, list): for host in ceph_hosts: if host.get('port'): xml += """ <host name='%s' port='%s'/>""" % ( host.get('name'), host.get('port')) else: xml += """ <host name='%s'/>""" % host.get('name') xml += """</source>""" else: xml += """<disk type='file' device='%s'>""" % volume['device'] xml += """ <driver name='qemu' type='%s' cache='%s' %s/>""" % ( volume['type'], cache_mode, OPTS.get("file", '')) xml += """ <source file='%s'/>""" % volume['path'] if volume['bus'] == 'virtio': xml += """<target dev='vd%s' bus='%s'/>""" % ( vd_disk_letters.pop(0), volume['bus']) elif volume['bus'] == 'ide': xml += """<target dev='hd%s' bus='%s'/>""" % ( hd_disk_letters.pop(0), volume['bus']) elif volume['bus'] == 'fdc': xml += """<target dev='fd%s' bus='%s'/>""" % ( fd_disk_letters.pop(0), volume['bus']) else: xml += """<target dev='sd%s' bus='%s'/>""" % ( sd_disk_letters.pop(0), volume['bus']) xml += """</disk>""" if add_cd: xml += """<disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file = '' /> <readonly/>""" if 'ide' in dom_caps['disk_bus']: xml += """<target dev='hd%s' bus='%s'/>""" % ( hd_disk_letters.pop(0), 'ide') elif 'sata' in dom_caps['disk_bus']: xml += """<target dev='sd%s' bus='%s'/>""" % ( sd_disk_letters.pop(0), 'sata') elif 'scsi' in dom_caps['disk_bus']: xml += """<target dev='sd%s' bus='%s'/>""" % ( sd_disk_letters.pop(0), 'scsi') else: xml += """<target dev='vd%s' bus='%s'/>""" % ( vd_disk_letters.pop(0), 'virtio') xml += """</disk>""" if volume['bus'] == 'scsi': xml += """<controller type='scsi' model='%s'/>""" % INSTANCE_VOLUME_DEFAULT_SCSI_CONTROLLER for net in networks.split(','): xml += """<interface type='network'>""" if mac: xml += """<mac address='%s'/>""" % mac xml += """<source network='%s'/>""" % net if nwfilter: xml += """<filterref filter='%s'/>""" % nwfilter if virtio: xml += """<model type='virtio'/>""" xml += """</interface>""" if console_pass == "random": console_pass = "******" + util.randomPasswd() + "'" else: if not console_pass == "": console_pass = "******" + console_pass + "'" xml += """<input type='mouse' bus='virtio'/>""" xml += """<input type='tablet' bus='virtio'/>""" xml += """ <graphics type='%s' port='-1' autoport='yes' %s listen='%s'/> <console type='pty'/> """ % (graphics, console_pass, listen_addr) if qemu_ga: xml += """ <channel type='unix'> <target type='virtio' name='org.qemu.guest_agent.0'/> </channel>""" xml += """ <video> <model type='%s'/> </video> </devices> </domain>""" % video self._defineXML(xml)
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())
def create_instance(self, name, memory, vcpu, host_model, uuid, images, cache_mode, networks, virtio, mac=None): """ Create VM function """ memory = int(memory) * 1024 if self.is_kvm_supported(): hypervisor_type = 'kvm' else: hypervisor_type = 'qemu' xml = """ <domain type='%s'> <name>%s</name> <description>None</description> <uuid>%s</uuid> <memory unit='KiB'>%s</memory> <vcpu>%s</vcpu>""" % (hypervisor_type, name, uuid, memory, vcpu) if host_model: xml += """<cpu mode='host-model'/>""" xml += """<os> <type arch='%s'>%s</type> <boot dev='hd'/> <boot dev='cdrom'/> <bootmenu enable='yes'/> </os>""" % (self.get_host_arch(), self.get_os_type()) xml += """<features> <acpi/><apic/><pae/> </features> <clock offset="utc"/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>restart</on_crash> <devices>""" disk_letters = list(string.lowercase) for image, img_type in images.items(): stg = self.get_storage_by_vol_path(image) stg_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type") if stg_type == 'rbd': ceph_user, secret_uuid, ceph_hosts = get_rbd_storage_data(stg) xml += """<disk type='network' device='disk'> <driver name='qemu' type='%s' cache='%s'/> <auth username='******'> <secret type='ceph' uuid='%s'/> </auth> <source protocol='rbd' name='%s'>""" % ( img_type, cache_mode, ceph_user, secret_uuid, image) if isinstance(ceph_hosts, list): for host in ceph_hosts: if host.get('port'): xml += """ <host name='%s' port='%s'/>""" % ( host.get('name'), host.get('port')) else: xml += """ <host name='%s'/>""" % host.get('name') xml += """ </source>""" else: xml += """<disk type='file' device='disk'> <driver name='qemu' type='%s' cache='%s'/> <source file='%s'/>""" % (img_type, cache_mode, image) if virtio: xml += """<target dev='vd%s' bus='virtio'/>""" % ( disk_letters.pop(0), ) else: xml += """<target dev='sd%s' bus='ide'/>""" % ( disk_letters.pop(0), ) xml += """</disk>""" xml += """ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file=''/> <target dev='hda' bus='ide'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='1'/> </disk>""" for net in networks.split(','): xml += """<interface type='network'>""" if mac: xml += """<mac address='%s'/>""" % mac xml += """<source network='%s'/>""" % net if virtio: xml += """<model type='virtio'/>""" xml += """</interface>""" xml += """ <input type='mouse' bus='ps2'/> <input type='tablet' bus='usb'/> <graphics type='%s' port='-1' autoport='yes' listen='0.0.0.0' passwd='%s'> <listen type='address' address='0.0.0.0'/> </graphics> <console type='pty'/> <video> <model type='cirrus'/> </video> <memballoon model='virtio'/> </devices> </domain>""" % (QEMU_CONSOLE_DEFAULT_TYPE, util.randomPasswd()) self._defineXML(xml)
def create_instance(self, name, memory, vcpu, host_model, uuid, images, cache_mode, networks, virtio, mac=None): """ Create VM function """ memory = int(memory) * 1024 if self.is_kvm_supported(): hypervisor_type = 'kvm' else: hypervisor_type = 'qemu' xml = """ <domain type='%s'> <name>%s</name> <description>None</description> <uuid>%s</uuid> <memory unit='KiB'>%s</memory> <vcpu>%s</vcpu>""" % (hypervisor_type, name, uuid, memory, vcpu) if host_model: xml += """<cpu mode='host-model'/>""" xml += """<os> <type arch='%s'>%s</type> <boot dev='hd'/> <boot dev='cdrom'/> <bootmenu enable='yes'/> </os>""" % (self.get_host_arch(), self.get_os_type()) xml += """<features> <acpi/><apic/><pae/> </features> <clock offset="utc"/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>restart</on_crash> <devices>""" disk_letters = list(string.lowercase) for image, img_type in images.items(): stg = self.get_storage_by_vol_path(image) stg_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type") if stg_type == 'rbd': ceph_user, secret_uuid, ceph_hosts = get_rbd_storage_data(stg) xml += """<disk type='network' device='disk'> <driver name='qemu' type='%s' cache='%s'/> <auth username='******'> <secret type='ceph' uuid='%s'/> </auth> <source protocol='rbd' name='%s'>""" % (img_type, cache_mode, ceph_user, secret_uuid, image) if isinstance(ceph_hosts, list): for host in ceph_hosts: if host.get('port'): xml += """ <host name='%s' port='%s'/>""" % (host.get('name'), host.get('port')) else: xml += """ <host name='%s'/>""" % host.get('name') xml += """ </source>""" else: xml += """<disk type='file' device='disk'> <driver name='qemu' type='%s' cache='%s'/> <source file='%s'/>""" % (img_type, cache_mode, image) if virtio: xml += """<target dev='vd%s' bus='virtio'/>""" % (disk_letters.pop(0),) else: xml += """<target dev='sd%s' bus='ide'/>""" % (disk_letters.pop(0),) xml += """</disk>""" xml += """ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file=''/> <target dev='hda' bus='ide'/> <readonly/> <address type='drive' controller='0' bus='1' target='0' unit='1'/> </disk>""" for net in networks.split(','): xml += """<interface type='network'>""" if mac: xml += """<mac address='%s'/>""" % mac xml += """<source network='%s'/>""" % net if virtio: xml += """<model type='virtio'/>""" xml += """</interface>""" xml += """ <input type='mouse' bus='ps2'/> <input type='tablet' bus='usb'/> <graphics type='%s' port='-1' autoport='yes' listen='0.0.0.0' passwd='%s'> <listen type='address' address='0.0.0.0'/> </graphics> <console type='pty'/> <video> <model type='cirrus'/> </video> <memballoon model='virtio'/> </devices> </domain>""" % (QEMU_CONSOLE_DEFAULT_TYPE, util.randomPasswd()) self._defineXML(xml)
def create_instance(self, name, memory, vcpu, host_model, uuid, images, cache_mode, networks, virtio, listen_addr, nwfilter=None, video="cirrus", console_pass="******", mac=None, qemu_ga=False): """ Create VM function """ memory = int(memory) * 1024 if self.is_kvm_supported(): hypervisor_type = 'kvm' else: hypervisor_type = 'qemu' xml = """ <domain type='%s'> <name>%s</name> <description>None</description> <uuid>%s</uuid> <memory unit='KiB'>%s</memory> <vcpu>%s</vcpu>""" % (hypervisor_type, name, uuid, memory, vcpu) if host_model: xml += """<cpu mode='host-model'/>""" xml += """<os> <type arch='%s'>%s</type> <boot dev='hd'/> <boot dev='cdrom'/> <bootmenu enable='yes'/> </os>""" % (self.get_host_arch(), self.get_os_type()) xml += """<features> <acpi/><apic/><pae/> </features> <clock offset="utc"/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>restart</on_crash> <devices>""" vd_disk_letters = list(string.lowercase) fd_disk_letters = list(string.lowercase) hd_disk_letters = list(string.lowercase) sd_disk_letters = list(string.lowercase) add_cd = True #for image, img_type in images.items(): for volume in images: stg = self.get_storage_by_vol_path(volume['path']) stg_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type") if volume['device'] == 'cdrom': add_cd = False if stg_type == 'rbd': ceph_user, secret_uuid, ceph_hosts = get_rbd_storage_data(stg) xml += """<disk type='network' device='disk'> <driver name='qemu' type='%s' cache='%s'/> <auth username='******'> <secret type='ceph' uuid='%s'/> </auth> <source protocol='rbd' name='%s'>""" % ( volume['type'], cache_mode, ceph_user, secret_uuid, volume['path']) if isinstance(ceph_hosts, list): for host in ceph_hosts: if host.get('port'): xml += """ <host name='%s' port='%s'/>""" % ( host.get('name'), host.get('port')) else: xml += """ <host name='%s'/>""" % host.get('name') xml += """ </source>""" else: xml += """<disk type='file' device='%s'> <driver name='qemu' type='%s' cache='%s'/> <source file='%s'/>""" % ( volume['device'], volume['type'], cache_mode, volume['path']) if volume['bus'] == 'virtio': xml += """<target dev='vd%s' bus='%s'/>""" % ( vd_disk_letters.pop(0), volume['bus']) elif volume['bus'] == 'ide': xml += """<target dev='hd%s' bus='%s'/>""" % ( hd_disk_letters.pop(0), volume['bus']) elif volume['bus'] == 'fdc': xml += """<target dev='fd%s' bus='%s'/>""" % ( fd_disk_letters.pop(0), volume['bus']) else: xml += """<target dev='sd%s' bus='%s'/>""" % ( sd_disk_letters.pop(0), volume['bus']) xml += """</disk>""" if add_cd: xml += """ <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file=''/> <target dev='hd%s' bus='ide'/> <readonly/> </disk>""" % (hd_disk_letters.pop(0), ) for net in networks.split(','): xml += """<interface type='network'>""" if mac: xml += """<mac address='%s'/>""" % mac xml += """<source network='%s'/>""" % net if nwfilter: xml += """<filterref filter='%s'/>""" % nwfilter if virtio: xml += """<model type='virtio'/>""" xml += """</interface>""" if console_pass == "random": console_pass = "******" + util.randomPasswd() + "'" else: if not console_pass == "": console_pass = "******" + console_pass + "'" xml += """ <input type='mouse' bus='ps2'/> <input type='tablet' bus='usb'/> <graphics type='%s' port='-1' autoport='yes' %s listen='%s'/> <console type='pty'/> """ % (QEMU_CONSOLE_DEFAULT_TYPE, console_pass, listen_addr) if qemu_ga: xml += """ <channel type='unix'> <target type='virtio' name='org.qemu.guest_agent.0'/> </channel>""" xml += """ <video> <model type='%s'/> </video> <memballoon model='virtio'/> </devices> </domain>""" % video self._defineXML(xml)
def create_instance( self, name, memory, vcpu, vcpu_mode, uuid, arch, machine, firmware, volumes, networks, nwfilter, graphics, virtio, listen_addr, video="vga", console_pass="******", mac=None, qemu_ga=True, ): """ Create VM function """ caps = self.get_capabilities(arch) dom_caps = self.get_dom_capabilities(arch, machine) memory = int(memory) * 1024 xml = f""" <domain type='{dom_caps["domain"]}'> <name>{name}</name> <description>None</description> <uuid>{uuid}</uuid> <memory unit='KiB'>{memory}</memory> <vcpu>{vcpu}</vcpu>""" if dom_caps["os_support"] == "yes": xml += f"""<os> <type arch='{arch}' machine='{machine}'>{caps["os_type"]}</type>""" xml += """ <boot dev='hd'/> <boot dev='cdrom'/> <bootmenu enable='yes'/>""" if firmware: if firmware["secure"] == "yes": xml += """<loader readonly='%s' type='%s' secure='%s'>%s</loader>""" % ( firmware["readonly"], firmware["type"], firmware["secure"], firmware["loader"], ) if firmware["secure"] == "no": xml += """<loader readonly='%s' type='%s'>%s</loader>""" % ( firmware["readonly"], firmware["type"], firmware["loader"], ) xml += """</os>""" if caps["features"]: xml += """<features>""" if "acpi" in caps["features"]: xml += """<acpi/>""" if "apic" in caps["features"]: xml += """<apic/>""" if "pae" in caps["features"]: xml += """<pae/>""" if firmware.get("secure", "no") == "yes": xml += """<smm state="on"/>""" xml += """</features>""" if vcpu_mode == "host-model": xml += """<cpu mode='host-model'/>""" elif vcpu_mode == "host-passthrough": xml += """<cpu mode='host-passthrough'/>""" elif vcpu_mode == "": pass else: xml += f"""<cpu mode='custom' match='exact' check='none'> <model fallback='allow'>{vcpu_mode}</model>""" xml += """</cpu>""" xml += """ <clock offset="utc"/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>restart</on_crash> """ xml += """<devices>""" vd_disk_letters = list(string.ascii_lowercase) fd_disk_letters = list(string.ascii_lowercase) hd_disk_letters = list(string.ascii_lowercase) sd_disk_letters = list(string.ascii_lowercase) add_cd = True for volume in volumes: disk_opts = "" if volume["cache_mode"] is not None and volume[ "cache_mode"] != "default": disk_opts += f"cache='{volume['cache_mode']}' " if volume["io_mode"] is not None and volume["io_mode"] != "default": disk_opts += f"io='{volume['io_mode']}' " if volume["discard_mode"] is not None and volume[ "discard_mode"] != "default": disk_opts += f"discard='{volume['discard_mode']}' " if volume["detect_zeroes_mode"] is not None and volume[ "detect_zeroes_mode"] != "default": disk_opts += f"detect_zeroes='{volume['detect_zeroes_mode']}' " stg = self.get_storage_by_vol_path(volume["path"]) stg_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type") if volume["device"] == "cdrom": add_cd = False if stg_type == "rbd": ceph_user, secret_uuid, ceph_hosts = get_rbd_storage_data(stg) xml += f"""<disk type='network' device='disk'> <driver name='qemu' type='{volume["type"]}' {disk_opts} />""" xml += f""" <auth username='******'> <secret type='ceph' uuid='{secret_uuid}'/> </auth> <source protocol='rbd' name='{volume["path"]}'>""" if isinstance(ceph_hosts, list): for host in ceph_hosts: if host.get("port"): xml += f""" <host name='{host.get("name")}' port='{host.get("port")}'/>""" else: xml += f"""<host name='{host.get("name")}'/>""" xml += """</source>""" else: xml += f"""<disk type='file' device='{volume["device"]}'>""" xml += f""" <driver name='qemu' type='{volume["type"]}' {disk_opts}/>""" xml += f""" <source file='{volume["path"]}'/>""" if volume.get("bus") == "virtio": xml += """<target dev='vd%s' bus='%s'/>""" % ( vd_disk_letters.pop(0), volume.get("bus")) elif volume.get("bus") == "ide": xml += """<target dev='hd%s' bus='%s'/>""" % ( hd_disk_letters.pop(0), volume.get("bus")) elif volume.get("bus") == "fdc": xml += """<target dev='fd%s' bus='%s'/>""" % ( fd_disk_letters.pop(0), volume.get("bus")) elif volume.get("bus") == "sata" or volume.get("bus") == "scsi": xml += """<target dev='sd%s' bus='%s'/>""" % ( sd_disk_letters.pop(0), volume.get("bus")) else: xml += """<target dev='sd%s'/>""" % sd_disk_letters.pop(0) xml += """</disk>""" if volume.get("bus") == "scsi": xml += f"""<controller type='scsi' model='{volume.get('scsi_model')}'/>""" if add_cd: xml += """<disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file = '' /> <readonly/>""" if "ide" in dom_caps["disk_bus"]: xml += """<target dev='hd%s' bus='%s'/>""" % ( hd_disk_letters.pop(0), "ide") elif "sata" in dom_caps["disk_bus"]: xml += """<target dev='sd%s' bus='%s'/>""" % ( sd_disk_letters.pop(0), "sata") elif "scsi" in dom_caps["disk_bus"]: xml += """<target dev='sd%s' bus='%s'/>""" % ( sd_disk_letters.pop(0), "scsi") else: xml += """<target dev='vd%s' bus='%s'/>""" % ( vd_disk_letters.pop(0), "virtio") xml += """</disk>""" if mac: macs = mac.split(',') for idx, net in enumerate(networks.split(",")): xml += """<interface type='network'>""" if mac: xml += f"""<mac address='{macs[idx]}'/>""" xml += f"""<source network='{net}'/>""" if nwfilter: xml += f"""<filterref filter='{nwfilter}'/>""" if virtio: xml += """<model type='virtio'/>""" xml += """</interface>""" if console_pass == "random": console_pass = "******" + util.randomPasswd() + "'" else: if not console_pass == "": console_pass = "******" + console_pass + "'" if "usb" in dom_caps["disk_bus"]: xml += """<input type='mouse' bus='{}'/>""".format( "virtio" if virtio else "usb") xml += """<input type='keyboard' bus='{}'/>""".format( "virtio" if virtio else "usb") xml += """<input type='tablet' bus='{}'/>""".format( "virtio" if virtio else "usb") else: xml += """<input type='mouse'/>""" xml += """<input type='keyboard'/>""" xml += """<input type='tablet'/>""" xml += f""" <graphics type='{graphics}' port='-1' autoport='yes' {console_pass} listen='{listen_addr}'/> <console type='pty'/> """ if qemu_ga and virtio: xml += """ <channel type='unix'> <target type='virtio' name='org.qemu.guest_agent.0'/> </channel>""" xml += f""" <video> <model type='{video}'/> </video> </devices> </domain>""" self._defineXML(xml)
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())
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 and (request.user.is_superuser or userinstace.is_delete): 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 and (request.user.is_superuser or userinstace.is_change): 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 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 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) 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())
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() 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 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 '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 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 '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) 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) 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())