diff --git a/computes/templates/overview.html b/computes/templates/overview.html index 81398b9..e6f824f 100644 --- a/computes/templates/overview.html +++ b/computes/templates/overview.html @@ -52,14 +52,33 @@

{{ hostname }}

-

{% for arch, hpv in hypervisor.items %} - - {{ arch }} - {% for h in hpv %} - {{ h }} - {% endfor %} - {% endfor %} -

+

+ {% for arch, hpv in hypervisor.items %} + {% if forloop.counter < 4 %} +
+ + +
+ {% else %} + + + {% endif %} + {% endfor %} +

{{ emulator }}

Qemu diff --git a/dev/libvirt-bootstrap.sh b/dev/libvirt-bootstrap.sh index c01a071..0f878a9 100644 --- a/dev/libvirt-bootstrap.sh +++ b/dev/libvirt-bootstrap.sh @@ -396,7 +396,8 @@ install_centos_post() { exit 1 fi if [ -f /etc/libvirt/qemu.conf ]; then - sed -i 's/#vnc_listen/vnc_listen/g' /etc/libvirt/qemu.conf + sed -i 's/#[ ]*vnc_listen.*/vnc_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf + sed -i 's/#[ ]*spice_listen.*/spice_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf else echoerror "/etc/libvirt/qemu.conf not found. Exiting..." exit 1 @@ -487,7 +488,8 @@ install_fedora_post() { exit 1 fi if [ -f /etc/libvirt/qemu.conf ]; then - sed -i 's/#vnc_listen/vnc_listen/g' /etc/libvirt/qemu.conf + sed -i 's/#[ ]*vnc_listen.*/vnc_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf + sed -i 's/#[ ]*spice_listen.*/spice_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf else echoerror "/etc/libvirt/qemu.conf not found. Exiting..." exit 1 @@ -548,7 +550,8 @@ install_opensuse_post() { exit 1 fi if [ -f /etc/libvirt/qemu.conf ]; then - sed -i 's/#vnc_listen/vnc_listen/g' /etc/libvirt/qemu.conf + sed -i 's/#[ ]*vnc_listen.*/vnc_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf + sed -i 's/#[ ]*spice_listen.*/spice_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf else echoerror "/etc/libvirt/qemu.conf not found. Exiting..." exit 1 @@ -618,11 +621,9 @@ install_ubuntu_post() { exit 1 fi if [ -f /etc/libvirt/qemu.conf ]; then - if ([ $DISTRO_MAJOR_VERSION -eq 12 ] && [ $DISTRO_MINOR_VERSION -eq 04 ]); then - sed -i 's/# vnc_listen/vnc_listen/g' /etc/libvirt/qemu.conf - else - sed -i 's/#vnc_listen/vnc_listen/g' /etc/libvirt/qemu.conf - fi + sed -i 's/#[ ]*vnc_listen.*/vnc_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf + sed -i 's/#[ ]*spice_listen.*/spice_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf + else echoerror "/etc/libvirt/qemu.conf not found. Exiting..." exit 1 @@ -663,9 +664,9 @@ daemons_running_ubuntu() { install_debian() { apt-get update || return 1 if [ $DISTRO_MAJOR_VERSION -lt 10 ]; then - apt-get -y install qemu-kvm libvirt-bin bridge-utils sasl2-bin python-guestfs supervisor || return 1 + apt-get -y install qemu-kvm libvirt-bin bridge-utils sasl2-bin python-guestfs supervisor || return 1 else - apt-get -y install qemu qemu-kvm qemu-system qemu-utils libvirt-clients libvirt-daemon-system sasl2-bin virtinst supervisor || return 1 + apt-get -y install qemu qemu-kvm qemu-system qemu-utils libvirt-clients libvirt-daemon-system sasl2-bin virtinst supervisor || return 1 fi return 0 } @@ -697,11 +698,19 @@ install_debian_post() { exit 1 fi if [ -f /etc/libvirt/qemu.conf ]; then - sed -i 's/# vnc_listen/vnc_listen/g' /etc/libvirt/qemu.conf + sed -i 's/#[ ]*vnc_listen.*/vnc_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf + sed -i 's/#[ ]*spice_listen.*/spice_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf else echoerror "/etc/libvirt/qemu.conf not found. Exiting..." exit 1 fi + if [ -f /etc/sasl2/libvirt.conf ]; then + sed -i 's/: gssapi/: digest-md5/g' /etc/sasl2/libvirt.conf + sed -i 's/#sasldb_path/sasldb_path/g' /etc/sasl2/libvirt.conf + else + echoerror "/etc/sasl2/libvirt.conf not found. Exiting..." + exit 1 + fi if [ -f /etc/supervisor/supervisord.conf ]; then wget -O /usr/local/bin/gstfsd https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/daemon/gstfsd chmod +x /usr/local/bin/gstfsd diff --git a/instances/templates/instance.html b/instances/templates/instance.html index 00ab3bb..5b6d3cd 100644 --- a/instances/templates/instance.html +++ b/instances/templates/instance.html @@ -363,10 +363,11 @@

{% if request.user.is_superuser or request.user.is_staff or userinstance.is_change %} + {% if status == 5 or not vcpus %}
{% csrf_token %}

{% trans "Logical host CPUs" %} : {{ vcpu_host }}

- +
{% for cpu in vcpu_range %} @@ -396,6 +397,28 @@ {% endifequal %} +
+ {% else %} +

{% trans "Logical Instance Active/Maximum CPUs" %} : {{ cur_vcpu }} / {{ vcpu }}

+
+
+ {% for id, vcpu in vcpus.items %} +
{% csrf_token %} +
+ + {% if vcpu.enabled == 'yes' and vcpu.hotpluggable == "yes" %} + + {% elif vcpu.enabled == 'yes' and vcpu.hotpluggable == "no" %} + + {% else %} + + {% endif %} +
+
+ {% endfor %} +
+
+ {% endif %} {% else %} {% trans "You don't have permission for resizing instance" %} @@ -1358,6 +1381,30 @@
+
+

{% trans "To set instance vCPUs hotpluggable" %}

+
{% csrf_token %} +
+ +
+
+ + + {% if status == 5 %} + + {% else %} + + {% endif %} + +
+
+
+
+
+
{% endif %}
diff --git a/instances/views.py b/instances/views.py index 51246ce..019234a 100644 --- a/instances/views.py +++ b/instances/views.py @@ -26,6 +26,7 @@ from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE from logs.views import addlogmsg from django.conf import settings from django.contrib import messages +from collections import OrderedDict @login_required @@ -44,7 +45,7 @@ def allinstances(request): :param request: :return: """ - all_host_vms = {} + all_host_vms = OrderedDict() error_messages = [] computes = Compute.objects.all().order_by("name") @@ -76,7 +77,7 @@ def instances(request, compute_id): :param compute_id :return: """ - all_host_vms = {} + all_host_vms = OrderedDict() error_messages = [] compute = get_object_or_404(Compute, pk=compute_id) @@ -266,6 +267,7 @@ def instance(request, compute_id, vname): boot_order = conn.get_bootorder() vcpu = conn.get_vcpu() cur_vcpu = conn.get_cur_vcpu() + vcpus = conn.get_vcpus() uuid = conn.get_uuid() memory = conn.get_memory() cur_memory = conn.get_cur_memory() @@ -668,6 +670,29 @@ def instance(request, compute_id, vname): addlogmsg(request.user.username, instance.name, msg) return HttpResponseRedirect(request.get_full_path() + '#suspend') + if 'set_vcpu' in request.POST: + id = request.POST.get('id', '') + enabled = request.POST.get('set_vcpu', '') + if enabled == 'True': + conn.set_vcpu(id, 1) + else: + conn.set_vcpu(id, 0) + msg = _("vCPU {} is enabled={}".format(id, enabled)) + messages.success(request, msg) + addlogmsg(request.user.username, instance.name, msg) + return HttpResponseRedirect(request.get_full_path() + '#resize') + + if 'set_vcpu_hotplug' in request.POST: + status = request.POST.get('vcpu_hotplug', '') + msg = _("vCPU Hot-plug is enabled={}".format(status)) + try: + conn.set_vcpu_hotplug(eval(status)) + except libvirtError as lib_err: + messages.error(request, lib_err.message) + messages.success(request, msg) + addlogmsg(request.user.username, instance.name, msg) + return HttpResponseRedirect(request.get_full_path() + '#resize') + if 'set_autostart' in request.POST: conn.set_autostart(1) msg = _("Set autostart") @@ -1036,7 +1061,7 @@ def get_host_instances(request, comp): inst_on_db = Instance(compute_id=comp["id"], name=inst_name, uuid=info['uuid']) inst_on_db.save() - all_host_vms = {} + all_host_vms = OrderedDict() status = connection_manager.host_is_up(comp.type, comp.hostname) if status is True: diff --git a/vrtManager/instance.py b/vrtManager/instance.py index 9fe7d67..08ab9c2 100644 --- a/vrtManager/instance.py +++ b/vrtManager/instance.py @@ -5,10 +5,12 @@ try: VIR_DOMAIN_AFFECT_LIVE, VIR_DOMAIN_AFFECT_CONFIG except: from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE, VIR_MIGRATE_LIVE + from vrtManager import util from xml.etree import ElementTree from lxml import etree from datetime import datetime +from collections import OrderedDict from vrtManager.connection import wvmConnect from vrtManager.storage import wvmStorage from webvirtcloud.settings import QEMU_CONSOLE_TYPES @@ -184,6 +186,18 @@ class wvmInstance(wvmConnect): if cur_vcpu: return int(cur_vcpu) + def get_vcpus(self): + vcpus = OrderedDict() + tree = etree.fromstring(self._XMLDesc(0)) + for vcpu in tree.xpath("/domain/vcpus/vcpu"): + id = vcpu.get("id") + enabled = vcpu.get("enabled") + hotplug = vcpu.get("hotpluggable") + order = vcpu.get("order") + vcpus[id] = {"enabled": enabled, "hotpluggable": hotplug, "order": order} + + return vcpus + def get_memory(self): mem = util.get_xml_path(self._XMLDesc(0), "/domain/memory") return int(mem) / 1024 @@ -554,6 +568,35 @@ class wvmInstance(wvmConnect): cpu_usage['cpu'] = 0 return cpu_usage + def set_vcpu(self, cpu_id, enabled): + self.instance.setVcpu(str(cpu_id), enabled) + + def set_vcpu_hotplug(self, status, vcpus_hotplug=0): + """ vcpus_hotplug = 0 make all vpus hotpluggable """ + vcpus_hotplug = int(self.get_vcpu()) if vcpus_hotplug == 0 else vcpus_hotplug + if self.get_status() == 5: # shutoff + if status: + xml = """ """ + xml += """""" + for i in range(1, vcpus_hotplug): + xml += """""".format(i, i+1) + xml += """""" + + tree = etree.fromstring(self._XMLDesc(0)) + vcpus = tree.xpath("/domain/vcpus") + if not vcpus: + tree.append(etree.fromstring(xml)) + self._defineXML(etree.tostring(tree)) + else: + tree = etree.fromstring(self._XMLDesc(0)) + vcpus = tree.xpath("/domain/vcpus") + for vcpu in vcpus: + parent = vcpu.getparent() + parent.remove(vcpu) + self._defineXML(etree.tostring(tree)) + else: + raise libvirtError("Please shutdown the instance then try to enable vCPU hotplug") + def mem_usage(self): mem_usage = {} if self.get_status() == 1: @@ -785,51 +828,27 @@ class wvmInstance(wvmConnect): parent.append(etree.fromstring(video_xml)) self._defineXML(etree.tostring(tree)) - def resize(self, cur_memory, memory, cur_vcpu, vcpu, disks=[]): - """ - Function change ram and cpu on vds. - """ - memory = int(memory) * 1024 - cur_memory = int(cur_memory) * 1024 - # if dom is running change only ram - if self.get_status() == VIR_DOMAIN_RUNNING: - self.set_memory(cur_memory, VIR_DOMAIN_AFFECT_LIVE) - self.set_memory(cur_memory, VIR_DOMAIN_AFFECT_CONFIG) - return - - xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE) - tree = ElementTree.fromstring(xml) - - set_mem = tree.find('memory') - set_mem.text = str(memory) - set_cur_mem = tree.find('currentMemory') - set_cur_mem.text = str(cur_memory) - set_vcpu = tree.find('vcpu') - set_vcpu.text = vcpu - set_vcpu.set('current', cur_vcpu) - - for disk in disks: - source_dev = disk['path'] - vol = self.get_volume_by_path(source_dev) - vol.resize(disk['size_new']) - - new_xml = ElementTree.tostring(tree) - self._defineXML(new_xml) - def resize_cpu(self, cur_vcpu, vcpu): """ - Function change ram and cpu on vds. + Function change ram and cpu on instance. """ + is_vcpus_enabled = self.get_vcpus() + if is_vcpus_enabled: + self.set_vcpu_hotplug(False) + xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE) - tree = ElementTree.fromstring(xml) + tree = etree.fromstring(xml) set_vcpu = tree.find('vcpu') set_vcpu.text = vcpu set_vcpu.set('current', cur_vcpu) - new_xml = ElementTree.tostring(tree) + new_xml = etree.tostring(tree) self._defineXML(new_xml) + if is_vcpus_enabled: + self.set_vcpu_hotplug(True, int(cur_vcpu)) + def resize_mem(self, cur_memory, memory): """ Function change ram and cpu on vds. diff --git a/webvirtcloud/settings.py.template b/webvirtcloud/settings.py.template index 88078be..58469f0 100644 --- a/webvirtcloud/settings.py.template +++ b/webvirtcloud/settings.py.template @@ -103,8 +103,8 @@ WS_PORT = 6080 # Websock host WS_HOST = '0.0.0.0' -# Websock public port -WS_PUBLIC_PORT = '443' +# Websock public port - 80 or 443 if reverse-proxy, else 6080 +WS_PUBLIC_PORT = 6080 # Websock public host WS_PUBLIC_HOST = None