def create_instance_select_type(request, compute_id): """ :param request: :param compute_id: :return: """ conn = None error_messages = list() storages = list() networks = list() hypervisors = list() meta_prealloc = False compute = get_object_or_404(Compute, pk=compute_id) appsettings = AppSettings.objects.all() try: conn = wvmCreate(compute.hostname, compute.login, compute.password, compute.type) instances = conn.get_instances() all_hypervisors = conn.get_hypervisors_machines() # Supported hypervisors by webvirtcloud: i686, x86_64(for now) supported_arch = [ "x86_64", "i686", "aarch64", "armv7l", "ppc64", "ppc64le", "s390x" ] hypervisors = [ hpv for hpv in all_hypervisors.keys() if hpv in supported_arch ] default_machine = appsettings.get( key="INSTANCE_MACHINE_DEFAULT_TYPE").value default_arch = appsettings.get(key="INSTANCE_ARCH_DEFAULT_TYPE").value if request.method == 'POST': 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('instances:instance', args=[compute_id, name])) except libvirtError as lib_err: error_messages.append(lib_err) except libvirtError as lib_err: error_messages.append(lib_err) return render(request, 'create_instance_w1.html', locals())
def setUpClass(cls): super().setUpClass() # Add users for testing purposes User = get_user_model() cls.admin_user = User.objects.get(pk=1) cls.test_user = User.objects.create(username='******') UserAttributes.objects.create( user=cls.test_user, max_instances=1, max_cpus=1, max_memory=128, max_disk_size=1, ) permission = Permission.objects.get(codename='clone_instances') cls.test_user.user_permissions.add(permission) # Add localhost compute cls.compute = Compute( name='test-compute', hostname='localhost', login='', password='', details='local', type=4, ) cls.compute.save() cls.connection = wvmCreate( cls.compute.hostname, cls.compute.login, cls.compute.password, cls.compute.type, ) # Add disks for testing cls.connection.create_volume( 'default', 'test-volume', 1, 'qcow2', False, 0, 0, ) # XML for testing vm with open('conf/test-vm.xml', 'r') as f: cls.xml = f.read() # Create testing vm from XML cls.connection._defineXML(cls.xml) refr(cls.compute) cls.instance: Instance = Instance.objects.get(pk=1)
def setUpClass(cls): super().setUpClass() # Add users for testing purposes User = get_user_model() cls.admin_user = User.objects.get(pk=1) cls.test_user = User.objects.create_user(username='******', password='******') # Add localhost compute cls.compute = Compute( name='test-compute', hostname='localhost', login='', password='', details='local', type=4, ) cls.compute.save() cls.connection = wvmCreate( cls.compute.hostname, cls.compute.login, cls.compute.password, cls.compute.type, ) # Add disks for testing cls.connection.create_volume( 'default', 'test-volume', 1, 'qcow2', False, 0, 0, ) # XML for testing vm with open('conf/test-vm.xml', 'r') as f: cls.xml = f.read() # Create testing vm from XML cls.connection._defineXML(cls.xml) refr(cls.compute) cls.instance = Instance.objects.get(pk=1)
def do_execute(self, quick_model: create_models.QuickVM): vcpu_num = quick_model.vcpu memory = quick_model.memory clock = quick_model.clock network = quick_model.network if not quick_model.disks_path: raise Exception('no disk') compute = compute_models.Compute.objects.get(id=quick_model.compute_id) conn = wvmCreate(compute.hostname, compute.login, compute.password, compute.type) uuid = util.randomUUID() #path = conn.get_volume_path(vol) #volumes[path] = conn.get_volume_type(path) disks = quick_model.disks_path.split(',') volumes = {} for disk_path in disks: volumes[disk_path] = conn.get_volume_type(disk_path) data = { 'uuid': uuid, 'name': quick_model.token, 'memory': memory, 'vcpu': vcpu_num, 'images': volumes, 'host_model': True, 'cache_mode': 'default', 'networks': network, 'virtio': True, 'clock': clock, } console_type = quick_model.console_type video_mode = quick_model.video_mode conn.create_instance(**data, console_type=console_type, video_model=video_mode) create_instance = Instance(compute_id=quick_model.compute_id, name=data['name'], uuid=uuid) create_instance.save() quick_model.instance = create_instance quick_model.save()
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(request, host_id): """ Create new instance. """ if not request.user.is_authenticated(): return HttpResponseRedirect(reverse('login')) conn = None errors = [] storages = [] networks = [] meta_prealloc = False compute = Compute.objects.get(id=host_id) flavors = Flavor.objects.filter().order_by('id') try: conn = wvmCreate(compute.hostname, compute.login, compute.password, compute.type) storages = sorted(conn.get_storages()) networks = sorted(conn.get_networks()) instances = conn.get_instances() get_images = sorted(conn.get_storages_images()) cache_modes = sorted(conn.get_cache_modes().items()) mac_auto = util.randomMAC() except libvirtError as err: errors.append(err) if conn: if not storages: msg = _("You haven't defined have any storage pools") errors.append(msg) if not networks: msg = _("You haven't defined have any network pools") errors.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('from_xml', '') try: name = util.get_xml_path(xml, '/domain/name') except util.libxml2.parserError: name = None if name in instances: msg = _("A virtual machine with this name already exists") errors.append(msg) else: try: conn._defineXML(xml) return HttpResponseRedirect(reverse('instance', args=[host_id, name])) except libvirtError as err: errors.append(err.message) if 'create' in request.POST: volumes = {} 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") errors.append(msg) if not errors: if data['hdd_size']: if not data['mac']: msg = _("No Virtual Machine MAC has been entered") errors.append(msg) else: try: path = conn.create_volume(data['storage'], data['name'], data['hdd_size'], metadata=meta_prealloc) volumes[path] = conn.get_volume_type(path) except libvirtError as msg_error: errors.append(msg_error.message) elif data['template']: templ_path = conn.get_volume_path(data['template']) clone_path = conn.clone_from_template(data['name'], templ_path, metadata=meta_prealloc) volumes[clone_path] = conn.get_volume_type(clone_path) else: if not data['images']: msg = _("First you need to create or select an image") errors.append(msg) else: for vol in data['images'].split(','): try: path = conn.get_volume_path(vol) volumes[path] = conn.get_volume_type(path) except libvirtError as msg_error: errors.append(msg_error.message) if data['cache_mode'] not in conn.get_cache_modes(): msg = _("Invalid cache mode") errors.append(msg) if not errors: uuid = util.randomUUID() try: conn.create_instance(data['name'], data['memory'], data['vcpu'], data['host_model'], uuid, volumes, data['cache_mode'], data['networks'], data['virtio'], data['mac']) create_instance = Instance(compute_id=host_id, name=data['name'], uuid=uuid) create_instance.save() return HttpResponseRedirect(reverse('instance', args=[host_id, data['name']])) except libvirtError as err: if data['hdd_size']: conn.delete_volume(volumes.keys()[0]) errors.append(err) conn.close() return render_to_response('create.html', locals(), context_instance=RequestContext(request))
def create(request, host_id): """ Create new instance. """ if not request.user.is_authenticated(): return HttpResponseRedirect(reverse('login')) conn = None errors = [] storages = [] networks = [] meta_prealloc = False compute = Compute.objects.get(id=host_id) flavors = Flavor.objects.filter().order_by('id') try: conn = wvmCreate(compute.hostname, compute.login, compute.password, compute.type) storages = sorted(conn.get_storages()) networks = sorted(conn.get_networks()) instances = conn.get_instances() get_images = sorted(conn.get_storages_images()) mac_auto = util.randomMAC() except libvirtError as err: errors.append(err) if conn: if not storages: msg = _("You haven't defined have any storage pools") errors.append(msg) if not networks: msg = _("You haven't defined have any network pools") errors.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('from_xml', '') try: name = util.get_xml_path(xml, '/domain/name') except util.libxml2.parserError: name = None if name in instances: msg = _("A virtual machine with this name already exists") errors.append(msg) else: try: conn._defineXML(xml) return HttpResponseRedirect(reverse('instance', args=[host_id, name])) except libvirtError as err: errors.append(err.message) if 'create' in request.POST: volumes = {} 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") errors.append(msg) if not errors: if data['hdd_size']: if not data['mac']: msg = _("No Virtual Machine MAC has been entered") errors.append(msg) else: try: path = conn.create_volume(data['storage'], data['name'], data['hdd_size'], metadata=meta_prealloc) volumes[path] = conn.get_volume_type(path) except libvirtError as msg_error: errors.append(msg_error.message) elif data['template']: templ_path = conn.get_volume_path(data['template']) clone_path = conn.clone_from_template(data['name'], templ_path, metadata=meta_prealloc) volumes[clone_path] = conn.get_volume_type(clone_path) else: if not data['images']: msg = _("First you need to create or select an image") errors.append(msg) else: for vol in data['images'].split(','): try: path = conn.get_volume_path(vol) volumes[path] = conn.get_volume_type(path) except libvirtError as msg_error: errors.append(msg_error.message) if not errors: uuid = util.randomUUID() try: conn.create_instance(data['name'], data['memory'], data['vcpu'], data['host_model'], uuid, volumes, data['networks'], data['virtio'], data['mac']) create_instance = Instance(compute_id=host_id, name=data['name'], uuid=uuid) create_instance.save() return HttpResponseRedirect(reverse('instance', args=[host_id, data['name']])) except libvirtError as err: if data['hdd_size']: conn.delete_volume(volumes.keys()[0]) errors.append(err) conn.close() return render_to_response('create.html', locals(), context_instance=RequestContext(request))
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())
def create(request, host_id): """ Create new instance. """ if not request.user.is_authenticated(): return HttpResponseRedirect(reverse('login')) conn = None errors = [] ifaces_all = [] ifaces_all_name = "" storages = [] hd_resources = {} meta_prealloc = False compute = Compute.objects.get(id=host_id) flavors = Flavor.objects.filter().order_by('id') flavor_name_list = Flavor.objects.filter(label='label') memory_range = [2048, 4096, 6144, 8192, 16384] vcpu_range = None try: conn = wvmCreate(compute.hostname, compute.login, compute.password, compute.type) conn_interfaces = wvmInterfaces(compute.hostname, compute.login, compute.password, compute.type) ifaces = conn_interfaces.get_ifaces() storages = sorted(conn.get_storages()) instances = conn.get_instances() get_images = sorted(conn.get_storages_images()) if os.path.exists(util.get_hd_resources_conf()): hd_resources = util.load_hd_resources() mem_left = hd_resources["mem"] vcpu_left = hd_resources["vcpu"] hd_resources = util.filter_hd_resources(hd_resources) else: hd_resources = util.create_hd_resources() mem_left = hd_resources["mem"] vcpu_left = hd_resources["vcpu"] hd_resources = util.filter_hd_resources(hd_resources) memory_range = [ memory for memory in memory_range if memory/1024 <= mem_left ] vcpu_range = xrange(1, int(vcpu_left) + 1) except libvirtError as err: errors.append(err) if conn_interfaces: try: netdevs = conn_interfaces.get_net_device() except: netdevs = ['eth0', 'eth1'] if conn: if not storages: msg = _("You haven't defined have any storage pools") errors.append(msg) if request.method == 'POST': if 'create_flavor' in request.POST: form = FlavorAddForm(request.POST) if form.is_valid(): data = form.cleaned_data flavor_name_list = Flavor.objects.filter(label=data['label']) if flavor_name_list: msg = _("A virtual machine template with this name already exists") errors.append(msg) else: 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('from_xml', '') try: name = util.get_xml_path(xml, '/domain/name') except util.libxml2.parserError: name = None if name in instances: msg = _("A virtual machine with this name already exists") errors.append(msg) else: try: conn._defineXML(xml) return HttpResponseRedirect(reverse('instance', args=[host_id, name])) except libvirtError as err: errors.append(err.message) if 'create' in request.POST: volumes = {} interfaces = [] vm_vfs_info = {} form = NewVMForm(request.POST) if form.is_valid(): data = form.cleaned_data if instances: if data['name'] in instances: msg = _("A virtual machine with this name already exists") errors.append(msg) if not errors: if data['hdd_size']: try: path = conn.create_volume(data['storage'], data['name'], data['hdd_size'], metadata=meta_prealloc) volumes[path] = conn.get_volume_type(path) except libvirtError as msg_error: errors.append(msg_error.message) elif data['template']: templ_path = conn.get_volume_path(data['template']) clone_path = conn.clone_from_template(data['name'], templ_path, metadata=meta_prealloc) volumes[clone_path] = conn.get_volume_type(clone_path) ifaces_all = request.POST.getlist('interfaces') else: if not data['images']: msg = _("First you need to create or select an image") errors.append(msg) else: for vol in data['images'].split(','): try: path = conn.get_volume_path(vol) volumes[path] = conn.get_volume_type(path) except libvirtError as msg_error: errors.append(msg_error.message) if not errors: uuid = util.randomUUID() try: template_ver3_flag = True if data['template'].find("WiseGrid_V3") == -1: template_ver3_flag = False conn.create_instance(data['name'], data['cur_memory'], data['cur_vcpu'], uuid, volumes, ifaces_all, False, True, template_ver3_flag) create_instance = Instance(compute_id=host_id, name=data['name'], uuid=uuid) create_instance.save() vm_vfs_info[data['name']] = ifaces_all if not errors: util.update_vfs_fro_vm(vm_vfs_info) return HttpResponseRedirect(reverse('instance', args=[host_id, data['name']])) except libvirtError as err: if data['hdd_size']: conn.delete_volume(volumes.keys()[0]) errors.append(err) else: print form.errors errors.append(form.errors) conn.close() return HttpResponseRedirect(reverse('instances',args=[host_id,errors]))
def instances(request, host_id): """ Instances block """ if not request.user.is_authenticated(): return HttpResponseRedirect(reverse('login')) errors = [] instances = [] time_refresh = 8000 get_instances = [] cnt_max = settings.vf_cnt_max conn = None meta_prealloc = False compute = Compute.objects.get(id=host_id) memory_range = [2048, 4096, 6144, 8192, 16384] ifaces_all = util.get_free_vfs() ifaces_all = sorted(ifaces_all.iteritems(),key=lambda ax:ax[0]) try: conn = wvmInstances(compute.hostname, compute.login, compute.password, compute.type) conn_create = wvmCreate(compute.hostname, compute.login, compute.password, compute.type) conn_storage = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, 'Images') state = conn_storage.is_active() if state: conn_storage.refresh() volumes = conn_storage.update_volumes() conn_storage.close() else: volumes = None get_images = volumes get_instances = conn.get_instances() except libvirtError as err: pass # errors.append(err) for instance in get_instances: try: inst = Instance.objects.get(compute_id=host_id, name=instance) uuid = inst.uuid except Instance.DoesNotExist: uuid = conn.get_uuid(instance) inst = Instance(compute_id=host_id, name=instance, uuid=uuid) inst.save() instances.append({'name': instance, 'status': conn.get_instance_status(instance), 'uuid': uuid, 'memory': conn.get_instance_memory(instance), 'vcpu': conn.get_instance_vcpu(instance), 'has_managed_save_image': conn.get_instance_managed_save_image(instance)}) if conn: try: if request.method == 'POST': name = request.POST.get('name', '') if 'start' in request.POST: conn.start(name) return HttpResponseRedirect(request.get_full_path()) if 'shutdown' in request.POST: conn.shutdown(name) return HttpResponseRedirect(request.get_full_path()) if 'destroy' in request.POST: conn.force_shutdown(name) return HttpResponseRedirect(request.get_full_path()) if 'managedsave' in request.POST: conn.managedsave(name) return HttpResponseRedirect(request.get_full_path()) if 'deletesaveimage' in request.POST: conn.managed_save_remove(name) return HttpResponseRedirect(request.get_full_path()) if 'suspend' in request.POST: conn.suspend(name) return HttpResponseRedirect(request.get_full_path()) if 'resume' in request.POST: conn.resume(name) return HttpResponseRedirect(request.get_full_path()) if 'create' in request.POST: volumes = {} interfaces = [] vm_vfs_info = {} form = NewVMForm(request.POST) if form.is_valid(): data = form.cleaned_data if instances: if data['name'] in instances: msg = _("A virtual machine with this name already exists") errors.append(msg) if not errors: if data['hdd_size']: try: path = conn.create_volume(data['storage'], data['name'], data['hdd_size'], metadata=meta_prealloc) volumes[path] = conn.get_volume_type(path) except libvirtError as msg_error: errors.append(msg_error.message) elif data['template']: templ_path = conn_create.get_volume_path(data['template']) clone_path = conn_create.clone_from_template(data['name'], templ_path, metadata=meta_prealloc) volumes[clone_path] = conn_create.get_volume_type(clone_path) ifaces_all = request.POST.getlist('interfaces') else: if not data['images']: msg = _("First you need to create or select an image") errors.append(msg) else: for vol in data['images'].split(','): try: path = conn.get_volume_path(vol) volumes[path] = conn.get_volume_type(path) except libvirtError as msg_error: errors.append(msg_error.message) if not errors: uuid = util.randomUUID() try: template_ver3_flag = True if data['template'].find("WiseGrid_V3") == -1: template_ver3_flag = False conn_create.create_instance(data['name'], data['cur_memory'], data['cur_vcpu'], uuid, volumes, ifaces_all, False, True, template_ver3_flag) create_instance = Instance(compute_id=host_id, name=data['name'], uuid=uuid) create_instance.save() vm_vfs_info[data['name']] = ifaces_all if not errors: util.update_vfs_fro_vm(vm_vfs_info) return HttpResponseRedirect(reverse('instance', args=[host_id, data['name']])) except libvirtError as err: if data['hdd_size']: conn_create.delete_volume(volumes.keys()[0]) errors.append(err) else: print form.errors errors.append(form.errors) conn.close() conn_create.close() except libvirtError as err: errors.append(err) hd_resources = util.load_hd_resources() mem_left = hd_resources["mem"] vcpu_left = hd_resources["vcpu"] memory_range = [ memory for memory in memory_range if memory/1024 <= mem_left ] vcpu_range = xrange(1, int(vcpu_left) + 1) vcpu_memory_left_flag = True if len(list(vcpu_range)) == 0 or len(memory_range) == 0: vcpu_memory_left_flag = False return render_to_response('instances.html', locals(), context_instance=RequestContext(request))
def createlxc(request, host_id): """ Create new lxc container instance. """ if not request.user.is_authenticated(): return HttpResponseRedirect(reverse('login')) if not request.user.is_staff: raise PermissionDenied conn = None errors = [] storages = [] networks = [] compute = Compute.objects.get(id=host_id) instances = None wmstorage =None templatedb = {} templatelist = [] with open('/var/www/webvirtmgr/ansiblefunc/playbook/template','r') as template: lines = template.readlines() for line in lines: templatedb[line.split(',')[0]] = line.split(',')[1].strip() templatelist.append(line.split(',')[0]) try: conn = wvmCreate(compute.hostname, compute.login, compute.password, compute.type, compute.hypervisor) storages = sorted(conn.get_storages()) networks = sorted(conn.get_networks()) instances = conn.get_instances() get_images = sorted(conn.get_storages_images()) get_containtype = sorted(['operation system','application']) mac_auto = util.randomMAC() except libvirtError as err: errors.append(err) if conn: if not storages: msg = _("You haven't defined have any storage pools") errors.append(msg) if not networks: msg = _("You haven't defined have any network pools") errors.append(msg) if request.method == 'POST': if 'create' in request.POST: volumes = {} pathtuple=[] form = NewVMForm(request.POST) if form.is_valid(): data = form.cleaned_data if data['meta_prealloc']: meta_prealloc = True if data['name'] in instances: msg = _("A virtual machine with this name already exists") errors.append(msg) if not data['images']: msg = _("First you need to create or select an image") errors.append(msg) if not errors: for vol in data['images'].split(','): try: path = conn.get_volume_path(vol) volumes[path] = conn.get_volume_type(path) pathtuple.append(path) except libvirtError as msg_error: errors.append(msg_error.message) if not errors: uuid = util.randomUUID() try: root = data['images'].split(',')[0] print root rootimage = conn.get_volume_path(root) ostype={'os':'/sbin/init','app':'/bin/sh'} if not data['template']: lxcdeployjob = ansiblefunc.ans_func.AnsDeployJob(vmname=data['name'],memory=data['memory'],rootimage=rootimage,supervisorip= conn.host,network=data['networks'].split(','),inittype=ostype[form.data['containtype']], rootpass=form.data['rootpass'],cpu=form.data['vcpu'],installedpackage=form.data['packages'], images=pathtuple[1:]) else: lxcdeployjob = ansiblefunc.ans_func.AnsDeployJob(vmname=data['name'], memory=data['memory'], rootimage=rootimage, supervisorip= conn.host, network=data['networks'].split( ','), rootpass=form.data['rootpass'], cpu=form.data['vcpu'], images=[], templatename=data['template']) lxcdeployjob.deploy() time.sleep(2) return HttpResponseRedirect(reverse('instances', args=[host_id])) except libvirtError as err: if data['hdd_size']: conn.delete_volume(volumes.keys()[0]) errors.append(err) conn.close() return render_to_response('createlxc.html', locals(), context_instance=RequestContext(request))
def create_instance(request, compute_id): """ :param request: :return: """ if not request.user.is_authenticated(): return HttpResponseRedirect(reverse("index")) if not request.user.is_superuser: return HttpResponseRedirect(reverse("index")) conn = None error_messages = [] storages = [] networks = [] meta_prealloc = False computes = Compute.objects.all() 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()) networks = sorted(conn.get_networks()) instances = conn.get_instances() get_images = sorted(conn.get_storages_images()) cache_modes = sorted(conn.get_cache_modes().items()) mac_auto = util.randomMAC() 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("from_xml", "") try: name = util.get_xml_path(xml, "/domain/name") except util.libxml2.parserError: 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: volumes = {} 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 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 ) volumes[path] = conn.get_volume_type(path) except libvirtError as lib_err: error_messages.append(lib_err.message) elif data["template"]: templ_path = conn.get_volume_path(data["template"]) clone_path = conn.clone_from_template(data["name"], templ_path, metadata=meta_prealloc) volumes[clone_path] = conn.get_volume_type(clone_path) else: if not data["images"]: error_msg = _("First you need to create or select an image") error_messages.append(error_msg) else: for vol in data["images"].split(","): try: path = conn.get_volume_path(vol) volumes[path] = conn.get_volume_type(path) 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, volumes, data["cache_mode"], data["networks"], data["virtio"], data["mac"], ) create_instance = Instance(compute_id=compute_id, name=data["name"], uuid=uuid) create_instance.save() return HttpResponseRedirect(reverse("instance", args=[compute_id, data["name"]])) except libvirtError as lib_err: if data["hdd_size"]: conn.delete_volume(volumes.keys()[0]) error_messages.append(lib_err) conn.close() return render(request, "create_instance.html", locals())
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())
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())
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())