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 %}
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.