1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2024-12-24 23:25:24 +00:00

adding enable/disable cpu hotplug, live add/remove vcpu to instance.

This commit is contained in:
catborise 2019-11-29 14:48:24 +03:00
parent e4223dde5d
commit 49e179590e
3 changed files with 130 additions and 39 deletions

View file

@ -363,10 +363,11 @@
<div class="tab-content">
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="resizevm_cpu">
{% if request.user.is_superuser or request.user.is_staff or userinstance.is_change %}
{% if status == 5 or not vcpus %}
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
<p style="font-weight:bold;">{% trans "Logical host CPUs" %} : {{ vcpu_host }}</p>
<div class="form-group">
<label class="col-sm-4 control-label" style="font-weight:normal;"> {% trans "Current allocation" %}</label>
<label class="col-sm-4 control-label" style="font-weight:normal;"> {% trans "Current Allocation" %}</label>
<div class="col-sm-4">
<select name="cur_vcpu" class="form-control">
{% for cpu in vcpu_range %}
@ -380,7 +381,7 @@
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label" style="font-weight:normal;">{% trans "Maximum allocation" %}</label>
<label class="col-sm-4 control-label" style="font-weight:normal;">{% trans "Maximum Allocation" %}</label>
<div class="col-sm-4">
<select name="vcpu" class="form-control">
{% for cpu in vcpu_range %}
@ -396,6 +397,28 @@
<button class="btn btn-lg btn-success pull-right disabled">{% trans "Resize" %}</button>
{% endifequal %}
</form>
<div class="clearfix"></div>
{% else %}
<p style="font-weight:bold;">{% trans "Logical Instance Active/Maximum CPUs" %} : {{ cur_vcpu }} / {{ vcpu }} </p>
<div class="col-sm-3"></div>
<div class="col-sm-6">
{% for id, vcpu in vcpus.items %}
<form method="post" role="form">{% csrf_token %}
<div class="col-sm-3">
<input name="id" value="{{ id }}" hidden/>
{% if vcpu.enabled == 'yes' and vcpu.hotpluggable == "yes" %}
<button type="submit" class="btn btn-block btn-success" value="False" name="set_vcpu" title="Disable">{{ id }}</button>
{% elif vcpu.enabled == 'yes' and vcpu.hotpluggable == "no" %}
<button type="button" class="btn btn btn-block btn-info" title="Constant">{{ id }}</button>
{% else %}
<button type="submit" class="btn btn btn-block btn-default" value="True" name="set_vcpu" title="Enable">{{ id }}</button>
{% endif %}
</div>
</form>
{% endfor %}
</div>
<div class="col-sm-3"></div>
{% endif %}
{% else %}
{% trans "You don't have permission for resizing instance" %}
<button class="btn btn-lg btn-success pull-right disabled">{% trans "Resize" %}</button>
@ -1358,6 +1381,30 @@
</form>
<div class="clearfix"></div>
</div>
<div class="well">
<p>{% trans "To set instance vCPUs hotpluggable" %}</p>
<form class="form-horizontal" method="post" role="form">{% csrf_token %}
<div class="form-group">
<label for="video_model_select" class="col-sm-3 control-label">{% trans "vCPU Hot Plug" %}</label>
<div class="col-sm-6">
<div class="input-group">
<select id="vcpu_hotplug" class="form-control" name="vcpu_hotplug">
<option value="True" {% if vcpus %} selected {% endif %}>{% trans 'Enabled' %}</option>
<option value="False" {% if not vcpus %} selected {% endif %}>{% trans 'Disabled' %}</option>
</select>
<span class="input-group-btn">
{% if status == 5 %}
<button type="submit" class="btn btn-success" name="set_vcpu_hotplug">{% trans "Set" %}</button>
{% else %}
<button class="btn btn-success" name="set_vcpu_hotplug" disabled>{% trans "Set" %}</button>
{% endif %}
</span>
</div>
</div>
</div>
</form>
<div class="clearfix"></div>
</div>
</div>
{% endif %}
</div>

View file

@ -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:

View file

@ -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 = """ <vcpus>"""
xml += """<vcpu id='0' enabled='yes' hotpluggable='no' order='1'/>"""
for i in range(1, vcpus_hotplug):
xml += """<vcpu id='{}' enabled='yes' hotpluggable='yes' order='{}'/>""".format(i, i+1)
xml += """</vcpus>"""
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.