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

Merge pull request #317 from catborise/rets

fixes and updates
This commit is contained in:
Anatoliy Guskov 2020-06-07 20:03:34 +03:00 committed by GitHub
commit dff60e4be4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 337 additions and 224 deletions

View file

@ -1,5 +1,4 @@
FROM phusion/baseimage:0.11 FROM phusion/baseimage:0.11
MAINTAINER Jethro Yu <comet.jc@gmail.com>
RUN echo 'APT::Get::Clean=always;' >> /etc/apt/apt.conf.d/99AutomaticClean RUN echo 'APT::Get::Clean=always;' >> /etc/apt/apt.conf.d/99AutomaticClean

View file

@ -30,13 +30,13 @@ class UserSSHKey(models.Model):
class UserAttributes(models.Model): class UserAttributes(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE) user = models.OneToOneField(User, on_delete=models.CASCADE)
can_clone_instances = models.BooleanField(default=True) can_clone_instances = models.BooleanField(default=True)
max_instances = models.IntegerField(default=1, max_instances = models.IntegerField(default=2,
help_text="-1 for unlimited. Any integer value", help_text="-1 for unlimited. Any integer value",
validators=[ validators=[
MinValueValidator(-1), MinValueValidator(-1),
]) ])
max_cpus = models.IntegerField( max_cpus = models.IntegerField(
default=1, default=2,
help_text="-1 for unlimited. Any integer value", help_text="-1 for unlimited. Any integer value",
validators=[MinValueValidator(-1)], validators=[MinValueValidator(-1)],
) )

View file

@ -226,29 +226,30 @@
} }
} }
}); });
if (Boolean({{ status }}) === true) {
window.setInterval(function graph_usage() {
$.getJSON('{% url 'compute_graph' compute_id %}', function (data) {
cpuChart.data.labels.push(data.timeline);
memChart.data.labels.push(data.timeline);
window.setInterval(function graph_usage() { cpuChart.data.datasets[0].data.push(data.cpudata);
$.getJSON('{% url 'compute_graph' compute_id %}', function (data) { if (cpuChart.data.datasets[0].data.length > 10){
cpuChart.data.labels.push(data.timeline); cpuChart.data.labels.shift();
memChart.data.labels.push(data.timeline); cpuChart.data.datasets[0].data.shift();
}
memChart.options.scales.yAxes[0].ticks.max = parseInt(data.memdata.total / 1048576);
memChart.options.scales.yAxes[0].ticks.stepSize = parseInt(data.memdata.total / (1048576 * 5));
memChart.data.datasets[0].data.push(parseInt(data.memdata.usage / 1048576));
cpuChart.data.datasets[0].data.push(data.cpudata); if (memChart.data.datasets[0].data.length > 10){
if (cpuChart.data.datasets[0].data.length > 10){ memChart.data.labels.shift();
cpuChart.data.labels.shift(); memChart.data.datasets[0].data.shift();
cpuChart.data.datasets[0].data.shift(); }
}
memChart.options.scales.yAxes[0].ticks.max = parseInt(data.memdata.total / 1048576);
memChart.options.scales.yAxes[0].ticks.stepSize = parseInt(data.memdata.total / (1048576 * 5));
memChart.data.datasets[0].data.push(parseInt(data.memdata.usage / 1048576));
if (memChart.data.datasets[0].data.length > 10){ cpuChart.update();
memChart.data.labels.shift(); memChart.update();
memChart.data.datasets[0].data.shift(); });
} }, 5000);
}
cpuChart.update();
memChart.update();
});
}, 5000);
</script> </script>
{% endblock %} {% endblock %}

View file

@ -86,7 +86,8 @@ def overview(request, compute_id):
error_messages = [] error_messages = []
compute = get_object_or_404(Compute, pk=compute_id) compute = get_object_or_404(Compute, pk=compute_id)
status = 'true' if connection_manager.host_is_up(compute.type, compute.hostname) is True else 'false'
try: try:
conn = wvmHostDetails( conn = wvmHostDetails(
compute.hostname, compute.hostname,
@ -141,6 +142,14 @@ def compute_graph(request, compute_id):
def get_compute_disk_buses(request, compute_id, arch, machine, disk): def get_compute_disk_buses(request, compute_id, arch, machine, disk):
"""
:param request:
:param compute_id:
:param arch:
:param machine:
:param disk:
:return:
"""
data = dict() data = dict()
compute = get_object_or_404(Compute, pk=compute_id) compute = get_object_or_404(Compute, pk=compute_id)
try: try:
@ -169,6 +178,12 @@ def get_compute_disk_buses(request, compute_id, arch, machine, disk):
def get_compute_machine_types(request, compute_id, arch): def get_compute_machine_types(request, compute_id, arch):
"""
:param request:
:param compute_id:
:param arch:
:return:
"""
data = dict() data = dict()
try: try:
compute = get_object_or_404(Compute, pk=compute_id) compute = get_object_or_404(Compute, pk=compute_id)
@ -186,6 +201,13 @@ def get_compute_machine_types(request, compute_id, arch):
def get_compute_video_models(request, compute_id, arch, machine): def get_compute_video_models(request, compute_id, arch, machine):
"""
:param request:
:param compute_id:
:param arch:
:param machine:
:return:
"""
data = dict() data = dict()
try: try:
compute = get_object_or_404(Compute, pk=compute_id) compute = get_object_or_404(Compute, pk=compute_id)
@ -203,6 +225,13 @@ def get_compute_video_models(request, compute_id, arch, machine):
def get_dom_capabilities(request, compute_id, arch, machine): def get_dom_capabilities(request, compute_id, arch, machine):
"""
:param request:
:param compute_id:
:param arch:
:param machine:
:return:
"""
data = dict() data = dict()
try: try:
compute = get_object_or_404(Compute, pk=compute_id) compute = get_object_or_404(Compute, pk=compute_id)

View file

@ -1,10 +1,10 @@
import re import re
from django.shortcuts import render from django.shortcuts import render
from libvirt import libvirtError
from instances.models import Instance from instances.models import Instance
from vrtManager.instance import wvmInstance from vrtManager.instance import wvmInstance
from webvirtcloud.settings import WS_PUBLIC_PORT from webvirtcloud.settings import WS_PUBLIC_PORT
from webvirtcloud.settings import WS_PUBLIC_HOST from webvirtcloud.settings import WS_PUBLIC_HOST
from libvirt import libvirtError
def console(request): def console(request):

View file

@ -125,7 +125,7 @@
} }
</script> </script>
<script src="{% static "js/ace.js" %}"></script> <script src="{% static "js/ace/ace.js" %}"></script>
<script> <script>
var editor = ace.edit("editor"); var editor = ace.edit("editor");
editor.getSession().setMode("ace/mode/xml"); editor.getSession().setMode("ace/mode/xml");

View file

@ -1,14 +1,18 @@
from django.contrib import messages
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.urls import reverse from django.urls import reverse
from libvirt import libvirtError
from admin.decorators import superuser_only
from computes.models import Compute from computes.models import Compute
from create.models import Flavor from create.models import Flavor
from create.forms import FlavorAddForm, NewVMForm from create.forms import FlavorAddForm, NewVMForm
from instances.models import Instance from instances.models import Instance
from vrtManager.create import wvmCreate from vrtManager.create import wvmCreate
from vrtManager import util from vrtManager import util
from libvirt import libvirtError from logs.views import addlogmsg
from webvirtcloud.settings import QEMU_CONSOLE_LISTEN_ADDRESSES from webvirtcloud.settings import QEMU_CONSOLE_LISTEN_ADDRESSES
from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_CACHE from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_CACHE
from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_BUS from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_BUS
@ -21,14 +25,14 @@ from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_DISCARD
from webvirtcloud.settings import INSTANCE_ARCH_DEFAULT_TYPE from webvirtcloud.settings import INSTANCE_ARCH_DEFAULT_TYPE
from webvirtcloud.settings import INSTANCE_FIRMWARE_DEFAULT_TYPE from webvirtcloud.settings import INSTANCE_FIRMWARE_DEFAULT_TYPE
from django.contrib import messages
from logs.views import addlogmsg
from admin.decorators import superuser_only
@superuser_only @superuser_only
def create_instance_select_type(request, compute_id): def create_instance_select_type(request, compute_id):
"""
:param request:
:param compute_id:
:return:
"""
conn = None conn = None
error_messages = list() error_messages = list()
storages = list() storages = list()

View file

@ -8,6 +8,5 @@ urlpatterns = [
views.os_metadata_json, name='ds_openstack_metadata'), views.os_metadata_json, name='ds_openstack_metadata'),
url(r'^openstack/(?P<version>[\w\-\.]+)/user_data$', url(r'^openstack/(?P<version>[\w\-\.]+)/user_data$',
views.os_userdata, name='ds_openstack_userdata'), views.os_userdata, name='ds_openstack_userdata'),
url(r'^vdi/(?P<vname>[\w\-\.]+)/$', url(r'^vdi/(?P<compute_id>[0-9]+)/(?P<vname>[\w\-\.]+)/$', views.get_vdi_url, name='vdi_url'),
views.get_vdi_url, name='vdi_url'),
] ]

View file

@ -1,17 +1,22 @@
from django.shortcuts import render
from django.http import HttpResponse, Http404
from accounts.models import UserInstance, UserSSHKey
from instances.models import Instance
from vrtManager.instance import wvmInstance
from libvirt import libvirtError
import json import json
import socket import socket
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, Http404
from libvirt import libvirtError
from accounts.models import UserInstance, UserSSHKey
from computes.models import Compute
from vrtManager.instance import wvmInstance
OS_VERSIONS = ['latest', ''] OS_VERSIONS = ['latest', '']
OS_UUID = "iid-dswebvirtcloud" OS_UUID = "iid-dswebvirtcloud"
def os_index(request): def os_index(request):
"""
:param request:
:return:
"""
response = '\n'.join(OS_VERSIONS) response = '\n'.join(OS_VERSIONS)
return HttpResponse(response) return HttpResponse(response)
@ -59,6 +64,10 @@ def os_userdata(request, version):
def get_client_ip(request): def get_client_ip(request):
"""
:param request:
:return:
"""
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for: if x_forwarded_for:
ip = x_forwarded_for.split(',')[-1].strip() ip = x_forwarded_for.split(',')[-1].strip()
@ -68,6 +77,10 @@ def get_client_ip(request):
def get_hostname_by_ip(ip): def get_hostname_by_ip(ip):
"""
:param ip:
:return:
"""
try: try:
addrs = socket.gethostbyaddr(ip) addrs = socket.gethostbyaddr(ip)
except: except:
@ -75,23 +88,25 @@ def get_hostname_by_ip(ip):
return addrs[0] return addrs[0]
def get_vdi_url(request, vname): def get_vdi_url(request, compute_id, vname):
instance = Instance.objects.get(name=vname) """
compute = instance.compute :param request:
:param vname:
:return:
"""
compute = get_object_or_404(Compute, pk=compute_id)
data = {} data = {}
try: try:
conn = wvmInstance(compute.hostname, conn = wvmInstance(compute.hostname,
compute.login, compute.login,
compute.password, compute.password,
compute.type, compute.type,
instance.name) vname)
fqdn = get_hostname_by_ip(compute.hostname) fqdn = get_hostname_by_ip(compute.hostname)
url = "{}://{}:{}".format(conn.get_console_type(), fqdn, conn.get_console_port()) url = f"{conn.get_console_type()}://{fqdn}:{conn.get_console_port()}"
response = url response = url
return HttpResponse(response) return HttpResponse(response)
except libvirtError as lib_err: except libvirtError as lib_err:
err = "Error getting vdi url for {}".format(vname) err = f"Error getting vdi url for {vname}"
raise Http404(err) raise Http404(err)

View file

@ -1629,7 +1629,7 @@
{% ifequal status 3 %} {% ifequal status 3 %}
<button class="btn btn-lg btn-success disabled pull-right" name="delete">{% trans "Destroy" %}</button> <button class="btn btn-lg btn-success disabled pull-right" name="delete">{% trans "Destroy" %}</button>
{% else %} {% else %}
<form class="form-group" method="post" role="form">{% csrf_token %} <form method="post" role="form" id="delete_form">{% csrf_token %}
<div class="checkbox" style="margin-left: 8px;"> <div class="checkbox" style="margin-left: 8px;">
<label> <label>
<input type="checkbox" name="delete_disk" value="true" checked> <input type="checkbox" name="delete_disk" value="true" checked>
@ -1666,7 +1666,7 @@
{% endblock %} {% endblock %}
{% block script %} {% block script %}
<script src="{% static "js/ace.js" %}" type="text/javascript" charset="utf-8"></script> <script src="{% static "js/ace/ace.js" %}" type="text/javascript" charset="utf-8"></script>
<script> <script>
function get_volumes(compute_id, pool) { function get_volumes(compute_id, pool) {
get_vol_url = "/computes/" + compute_id + "/storage/" + pool + "/volumes"; get_vol_url = "/computes/" + compute_id + "/storage/" + pool + "/volumes";
@ -1817,7 +1817,7 @@
}); });
$(document).ready(function () { $(document).ready(function () {
// set vdi url // set vdi url
$.get("{% url 'vdi_url' vname %}", function(data) { $.get("{% url 'vdi_url' compute_id vname %}", function(data) {
$("#vdi_url_input").attr("value", data); $("#vdi_url_input").attr("value", data);
$("#vdi_url").attr("href", data); $("#vdi_url").attr("href", data);
}); });
@ -2136,7 +2136,7 @@
}); });
{% endfor %} {% endfor %}
window.setInterval(function graph_usage() { var graph_interval = window.setInterval(function graph_usage() {
$.getJSON('{% url 'inst_graph' compute_id vname %}', function (data) { $.getJSON('{% url 'inst_graph' compute_id vname %}', function (data) {
cpuChart.data.labels.push(data.timeline); cpuChart.data.labels.push(data.timeline);
@ -2187,15 +2187,21 @@
}); });
</script> </script>
<script> <script>
backgroundJobRunning = false; backgroundJobRunning = false;
window.setInterval(function get_status() { var status_interval = window.setInterval(function get_status() {
var status = {{ status|lower }}; var status = {{ status|lower }};
$.getJSON('{% url 'inst_status' compute_id vname %}', function (data) { $.getJSON('{% url 'inst_status' compute_id vname %}', function (data) {
if (data['status'] != status && !backgroundJobRunning) { if (data['status'] != status && !backgroundJobRunning) {
window.location.reload() window.location.reload()
} }
}); });
}, 5000); }, 5000);
// Stop getting status info before delete instance
$('#delete_form').submit(function(){
window.clearInterval(status_interval);
return true;
});
</script> </script>
<script> <script>
var hash = location.hash; var hash = location.hash;

View file

@ -128,15 +128,15 @@ def instance(request, compute_id, vname):
if size_str == '': if size_str == '':
return 0 return 0
size_str = size_str.upper().replace("B", "") size_str = size_str.upper().replace("B", "")
if 'K' == size_str[-1]: if size_str[-1] == 'K':
return int(float(size_str[:-1])) << 10 return int(float(size_str[:-1])) << 10
elif 'M' == size_str[-1]: elif size_str[-1] == 'M':
return int(float(size_str[:-1])) << 20 return int(float(size_str[:-1])) << 20
elif 'G' == size_str[-1]: elif size_str[-1] == 'G':
return int(float(size_str[:-1])) << 30 return int(float(size_str[:-1])) << 30
elif 'T' == size_str[-1]: elif size_str[-1] == 'T':
return int(float(size_str[:-1])) << 40 return int(float(size_str[:-1])) << 40
elif 'P' == size_str[-1]: elif size_str[-1] == 'P':
return int(float(size_str[:-1])) << 50 return int(float(size_str[:-1])) << 50
else: else:
return int(float(size_str)) return int(float(size_str))
@ -460,40 +460,6 @@ def instance(request, compute_id, vname):
msg = _("Please shutdown down your instance and then try again") msg = _("Please shutdown down your instance and then try again")
error_messages.append(msg) 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 'resizevm_cpu' in request.POST and ( if 'resizevm_cpu' in request.POST and (
request.user.is_superuser or request.user.is_staff or userinstance.is_change): request.user.is_superuser or request.user.is_staff or userinstance.is_change):
new_vcpu = request.POST.get('vcpu', '') new_vcpu = request.POST.get('vcpu', '')
@ -619,9 +585,9 @@ def instance(request, compute_id, vname):
if new_bus != bus: if new_bus != bus:
conn.detach_disk(target_dev) conn.detach_disk(target_dev)
conn.attach_disk(new_target_dev, new_path, target_bus=new_bus, conn.attach_disk(new_target_dev, new_path, target_bus=new_bus,
driver_type=format, cache_mode=cache, driver_type=format, cache_mode=cache,
readonly=readonly, shareable=shareable, serial=serial, readonly=readonly, shareable=shareable, serial=serial,
io_mode=io, discard_mode=discard, detect_zeroes_mode=zeroes) io_mode=io, discard_mode=discard, detect_zeroes_mode=zeroes)
else: else:
conn.edit_disk(target_dev, new_path, readonly, shareable, new_bus, serial, format, conn.edit_disk(target_dev, new_path, readonly, shareable, new_bus, serial, format,
cache, io, discard, zeroes) cache, io, discard, zeroes)
@ -669,7 +635,7 @@ def instance(request, compute_id, vname):
if 'add_cdrom' in request.POST and allow_admin_or_not_template: if 'add_cdrom' in request.POST and allow_admin_or_not_template:
bus = request.POST.get('bus', 'ide' if machine == 'pc' else 'sata') bus = request.POST.get('bus', 'ide' if machine == 'pc' else 'sata')
target = get_new_disk_dev(media, disks, bus) target = get_new_disk_dev(media, disks, bus)
conn.attach_disk(target, "", disk_device='cdrom', cache_mode='none', target_bus=bus, readonly=True) conn.attach_disk(target, "", disk_device='cdrom', cache_mode='none', target_bus=bus, readonly=True)
msg = _('Add CD-ROM: ' + target) msg = _('Add CD-ROM: ' + target)
addlogmsg(request.user.username, instance.name, msg) addlogmsg(request.user.username, instance.name, msg)
return HttpResponseRedirect(request.get_full_path() + '#disks') return HttpResponseRedirect(request.get_full_path() + '#disks')
@ -1467,4 +1433,3 @@ def delete_instance(instance, delete_disk=False):
except libvirtError as lib_err: except libvirtError as lib_err:
print("Error removing instance {} on compute {}".format(instance_name, compute.hostname)) print("Error removing instance {} on compute {}".format(instance_name, compute.hostname))
raise lib_err raise lib_err

View file

@ -465,7 +465,7 @@
}); });
}); });
</script> </script>
<script src="{% static "js/ace.js" %}"></script> <script src="{% static "js/ace/ace.js" %}"></script>
<script> <script>
var editor = ace.edit("edit_editor"); var editor = ace.edit("edit_editor");
editor.getSession().setMode("ace/mode/xml"); editor.getSession().setMode("ace/mode/xml");

View file

@ -178,7 +178,7 @@
}(jQuery)); }(jQuery));
}); });
</script> </script>
<script src="{% static "js/ace.js" %}"></script> <script src="{% static "js/ace/ace.js" %}"></script>
<script> <script>
var editor = ace.edit("edit_editor"); var editor = ace.edit("edit_editor");
editor.getSession().setMode("ace/mode/xml"); editor.getSession().setMode("ace/mode/xml");

View file

@ -156,7 +156,7 @@
}); });
</script> </script>
<script src="{% static "js/ace.js" %}"></script> <script src="{% static "js/ace/ace.js" %}"></script>
<script> <script>
var editor = ace.edit("editor"); var editor = ace.edit("editor");
editor.getSession().setMode("ace/mode/xml"); editor.getSession().setMode("ace/mode/xml");

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render from django.shortcuts import get_object_or_404, render
from django.urls import reverse from django.urls import reverse
@ -110,7 +107,12 @@ def nwfilters(request, compute_id):
def nwfilter(request, compute_id, nwfltr): def nwfilter(request, compute_id, nwfltr):
"""
:param request:
:param compute_id:
:param nwfltr:
:return:
"""
error_messages = [] error_messages = []
nwfilters_all = [] nwfilters_all = []
compute = get_object_or_404(Compute, pk=compute_id) compute = get_object_or_404(Compute, pk=compute_id)

File diff suppressed because one or more lines are too long

17
static/js/ace/ace.js Executable file

File diff suppressed because one or more lines are too long

View file

@ -5,3 +5,4 @@ define("ace/theme/textmate",["require","exports","module","ace/lib/dom"],functio
} }
}); });
})(); })();

1
static/js/mode-xml.js → static/js/ace/mode-xml.js Executable file → Normal file
View file

@ -5,3 +5,4 @@ define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop
} }
}); });
})(); })();

File diff suppressed because one or more lines are too long

4
static/js/jquery.js vendored

File diff suppressed because one or more lines are too long

View file

@ -1,3 +1,4 @@
import json
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect, HttpResponse from django.http import HttpResponseRedirect, HttpResponse
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -7,7 +8,6 @@ from storages.forms import AddStgPool, AddImage, CloneImage
from vrtManager.storage import wvmStorage, wvmStorages from vrtManager.storage import wvmStorage, wvmStorages
from libvirt import libvirtError from libvirt import libvirtError
from django.contrib import messages from django.contrib import messages
import json
from admin.decorators import superuser_only from admin.decorators import superuser_only
@ -200,6 +200,12 @@ def storage(request, compute_id, pool):
def get_volumes(request, compute_id, pool): def get_volumes(request, compute_id, pool):
"""
:param request:
:param compute_id: compute id
:param pool: pool name
:return: volumes list of pool
"""
data = {} data = {}
compute = get_object_or_404(Compute, pk=compute_id) compute = get_object_or_404(Compute, pk=compute_id)
try: try:

View file

@ -18,6 +18,8 @@ TCP_PORT = 16509
class wvmEventLoop(threading.Thread): class wvmEventLoop(threading.Thread):
""" Event Loop Class"""
def __init__(self, group=None, target=None, name=None, args=(), kwargs={}): def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
# register the default event implementation # register the default event implementation
# of libvirt, as we do not have an existing # of libvirt, as we do not have an existing
@ -309,16 +311,19 @@ class wvmConnectionManager(object):
socket_host.settimeout(1) socket_host.settimeout(1)
if conn_type == CONN_SSH: if conn_type == CONN_SSH:
if ':' in hostname: if ':' in hostname:
LIBVIRT_HOST, PORT = hostname.split(":") libvirt_host, PORT = hostname.split(":")
PORT = int(PORT) PORT = int(PORT)
else: else:
PORT = SSH_PORT PORT = SSH_PORT
LIBVIRT_HOST = hostname libvirt_host = hostname
socket_host.connect((LIBVIRT_HOST, PORT)) socket_host.connect((libvirt_host, PORT))
if conn_type == CONN_TCP: if conn_type == CONN_TCP:
socket_host.connect((hostname, TCP_PORT)) socket_host.connect((hostname, TCP_PORT))
if conn_type == CONN_TLS: if conn_type == CONN_TLS:
socket_host.connect((hostname, TLS_PORT)) socket_host.connect((hostname, TLS_PORT))
if conn_type == CONN_SOCKET:
socket_host = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
socket_host.connect('/var/run/libvirt/libvirt-sock')
socket_host.close() socket_host.close()
return True return True
except Exception as err: except Exception as err:
@ -387,7 +392,7 @@ class wvmConnect(object):
result = dict() result = dict()
xml = self.get_dom_cap_xml(arch, machine) xml = self.get_dom_cap_xml(arch, machine)
result["path"] = util.get_xml_path(xml,"/domainCapabilities/path") result["path"] = util.get_xml_path(xml, "/domainCapabilities/path")
result["domain"] = util.get_xml_path(xml, "/domainCapabilities/domain") result["domain"] = util.get_xml_path(xml, "/domainCapabilities/domain")
result["machine"] = util.get_xml_path(xml, "/domainCapabilities/machine") result["machine"] = util.get_xml_path(xml, "/domainCapabilities/machine")
result["vcpu_max"] = util.get_xml_path(xml, "/domainCapabilities/vcpu/@max") result["vcpu_max"] = util.get_xml_path(xml, "/domainCapabilities/vcpu/@max")
@ -431,6 +436,9 @@ class wvmConnect(object):
return result return result
def get_version(self): def get_version(self):
"""
:return: libvirt version
"""
ver = self.wvm.getVersion() ver = self.wvm.getVersion()
major = ver // 1000000 major = ver // 1000000
ver = ver % 1000000 ver = ver % 1000000
@ -449,10 +457,15 @@ class wvmConnect(object):
return f"{major}.{minor}.{release}" return f"{major}.{minor}.{release}"
def is_kvm_supported(self): def is_kvm_supported(self):
"""Return KVM capabilities.""" """
:return: kvm support or not
"""
return util.is_kvm_available(self.get_cap_xml()) return util.is_kvm_available(self.get_cap_xml())
def get_storages(self, only_actives=False): def get_storages(self, only_actives=False):
"""
:return: list of active or all storages
"""
storages = [] storages = []
for pool in self.wvm.listStoragePools(): for pool in self.wvm.listStoragePools():
storages.append(pool) storages.append(pool)
@ -462,6 +475,9 @@ class wvmConnect(object):
return storages return storages
def get_networks(self): def get_networks(self):
"""
:return: list of networks
"""
virtnet = [] virtnet = []
for net in self.wvm.listNetworks(): for net in self.wvm.listNetworks():
virtnet.append(net) virtnet.append(net)
@ -470,6 +486,9 @@ class wvmConnect(object):
return virtnet return virtnet
def get_ifaces(self): def get_ifaces(self):
"""
:return: list of network interfaces
"""
interface = [] interface = []
for inface in self.wvm.listInterfaces(): for inface in self.wvm.listInterfaces():
interface.append(inface) interface.append(inface)
@ -478,13 +497,18 @@ class wvmConnect(object):
return interface return interface
def get_nwfilters(self): def get_nwfilters(self):
"""
:return: list of network filters
"""
nwfilters = [] nwfilters = []
for nwfilter in self.wvm.listNWFilters(): for nwfilter in self.wvm.listNWFilters():
nwfilters.append(nwfilter) nwfilters.append(nwfilter)
return nwfilters return nwfilters
def get_cache_modes(self): def get_cache_modes(self):
"""Get cache available modes""" """
:return: Get cache available modes
"""
return { return {
'default': 'Default', 'default': 'Default',
'none': 'Disabled', 'none': 'Disabled',
@ -495,7 +519,9 @@ class wvmConnect(object):
} }
def get_io_modes(self): def get_io_modes(self):
"""Get io threads available modes""" """
:return: available io modes
"""
return { return {
'default': 'Default', 'default': 'Default',
'native': 'Native', 'native': 'Native',
@ -503,7 +529,9 @@ class wvmConnect(object):
} }
def get_discard_modes(self): def get_discard_modes(self):
"""Get discard available modes""" """
:return: available discard modes
"""
return { return {
'default': 'Default', 'default': 'Default',
'ignore': 'Ignore', 'ignore': 'Ignore',
@ -511,7 +539,9 @@ class wvmConnect(object):
} }
def get_detect_zeroes_modes(self): def get_detect_zeroes_modes(self):
"""Get detect zeroes available modes""" """
:return: available detect zeroes modes
"""
return { return {
'default': 'Default', 'default': 'Default',
'on': 'On', 'on': 'On',
@ -520,7 +550,9 @@ class wvmConnect(object):
} }
def get_hypervisors_domain_types(self): def get_hypervisors_domain_types(self):
"""Return hypervisor type""" """
:return: hypervisor domain types
"""
def hypervisors(ctx): def hypervisors(ctx):
result = {} result = {}
for arch in ctx.xpath('/capabilities/guest/arch'): for arch in ctx.xpath('/capabilities/guest/arch'):
@ -531,7 +563,9 @@ class wvmConnect(object):
return util.get_xml_path(self.get_cap_xml(), func=hypervisors) return util.get_xml_path(self.get_cap_xml(), func=hypervisors)
def get_hypervisors_machines(self): def get_hypervisors_machines(self):
"""Return hypervisor and its machine types""" """
:return: hypervisor and its machine types
"""
def machines(ctx): def machines(ctx):
result = dict() result = dict()
for arche in ctx.xpath('/capabilities/guest/arch'): for arche in ctx.xpath('/capabilities/guest/arch'):
@ -542,11 +576,15 @@ class wvmConnect(object):
return util.get_xml_path(self.get_cap_xml(), func=machines) return util.get_xml_path(self.get_cap_xml(), func=machines)
def get_emulator(self, arch): def get_emulator(self, arch):
"""Return emulator """ """
:return: emulator list
"""
return util.get_xml_path(self.get_cap_xml(), "/capabilities/guest/arch[@name='{}']/emulator".format(arch)) return util.get_xml_path(self.get_cap_xml(), "/capabilities/guest/arch[@name='{}']/emulator".format(arch))
def get_machine_types(self, arch): def get_machine_types(self, arch):
"""Return canonical(if exist) name of machine types """ """
:return: canonical(if exist) name of machine types
"""
def machines(ctx): def machines(ctx):
result = list() result = list()
canonical_name = ctx.xpath("/capabilities/guest/arch[@name='{}']/machine[@canonical]".format(arch)) canonical_name = ctx.xpath("/capabilities/guest/arch[@name='{}']/machine[@canonical]".format(arch))
@ -559,6 +597,9 @@ class wvmConnect(object):
return util.get_xml_path(self.get_cap_xml(), func=machines) return util.get_xml_path(self.get_cap_xml(), func=machines)
def get_emulators(self): def get_emulators(self):
"""
:return: host emulators list
"""
def emulators(ctx): def emulators(ctx):
result = {} result = {}
for arch in ctx.xpath('/capabilities/guest/arch'): for arch in ctx.xpath('/capabilities/guest/arch'):
@ -569,13 +610,21 @@ class wvmConnect(object):
return util.get_xml_path(self.get_cap_xml(), func=emulators) return util.get_xml_path(self.get_cap_xml(), func=emulators)
def get_os_loaders(self, arch='x86_64', machine='pc'): def get_os_loaders(self, arch='x86_64', machine='pc'):
"""Get available os loaders list""" """
:param arch: architecture
:param machine:
:return: available os loaders list
"""
def get_os_loaders(ctx): def get_os_loaders(ctx):
return [v.text for v in ctx.xpath("/domainCapabilities/os/loader[@supported='yes']/value")] return [v.text for v in ctx.xpath("/domainCapabilities/os/loader[@supported='yes']/value")]
return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_os_loaders) return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_os_loaders)
def get_os_loader_enums(self, arch, machine): def get_os_loader_enums(self, arch, machine):
"""Get available os loaders list""" """
:param arch: architecture
:param machine:
:return: available os loaders list
"""
def get_os_loader_enums(ctx): def get_os_loader_enums(ctx):
result = dict() result = dict()
enums = [v for v in ctx.xpath("/domainCapabilities/os/loader[@supported='yes']/enum/@name")] enums = [v for v in ctx.xpath("/domainCapabilities/os/loader[@supported='yes']/enum/@name")]
@ -586,33 +635,53 @@ class wvmConnect(object):
return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_os_loader_enums) return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_os_loader_enums)
def get_disk_bus_types(self, arch, machine): def get_disk_bus_types(self, arch, machine):
"""Get available disk bus types list""" """
:param machine:
:param arch:
:return: available disk bus types list
"""
def get_bus_list(ctx): def get_bus_list(ctx):
return [v.text for v in ctx.xpath("/domainCapabilities/devices/disk/enum[@name='bus']/value")] return [v.text for v in ctx.xpath("/domainCapabilities/devices/disk/enum[@name='bus']/value")]
# return [ 'ide', 'scsi', 'usb', 'virtio' ] # return [ 'ide', 'scsi', 'usb', 'virtio' ]
return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_bus_list) return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_bus_list)
def get_disk_device_types(self, arch, machine): def get_disk_device_types(self, arch, machine):
"""Get available disk device type list""" """
:param arch: architecture
:param machine:
:return: available disk device type list
"""
def get_device_list(ctx): def get_device_list(ctx):
return [v.text for v in ctx.xpath("/domainCapabilities/devices/disk/enum[@name='diskDevice']/value")] return [v.text for v in ctx.xpath("/domainCapabilities/devices/disk/enum[@name='diskDevice']/value")]
# return [ 'disk', 'cdrom', 'floppy', 'lun' ] # return [ 'disk', 'cdrom', 'floppy', 'lun' ]
return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_device_list) return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_device_list)
def get_graphics_types(self, arch, machine): def get_graphics_types(self, arch, machine):
"""Get available graphics types """ """
:param arch: architecture
:param machine:
:return: available graphics types
"""
def get_graphics_list(ctx): def get_graphics_list(ctx):
return [ v.text for v in ctx.xpath("/domainCapabilities/devices/graphics/enum[@name='type']/value")] return [v.text for v in ctx.xpath("/domainCapabilities/devices/graphics/enum[@name='type']/value")]
return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_graphics_list) return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_graphics_list)
def get_cpu_modes(self, arch, machine): def get_cpu_modes(self, arch, machine):
"""Get available cpu modes """ """
:param arch: architecture
:param machine:
:return: available cpu modes
"""
def get_cpu_modes(ctx): def get_cpu_modes(ctx):
return [v for v in ctx.xpath("/domainCapabilities/cpu/mode[@supported='yes']/@name")] return [v for v in ctx.xpath("/domainCapabilities/cpu/mode[@supported='yes']/@name")]
return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_cpu_modes) return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_cpu_modes)
def get_cpu_custom_types(self, arch, machine): def get_cpu_custom_types(self, arch, machine):
"""Get available graphics types """ """
:param arch: architecture
:param machine:
:return: available graphics types
"""
def get_custom_list(ctx): def get_custom_list(ctx):
usable_yes = "/domainCapabilities/cpu/mode[@name='custom'][@supported='yes']/model[@usable='yes']" usable_yes = "/domainCapabilities/cpu/mode[@name='custom'][@supported='yes']/model[@usable='yes']"
usable_unknown = "/domainCapabilities/cpu/mode[@name='custom'][@supported='yes']/model[@usable='unknown']" usable_unknown = "/domainCapabilities/cpu/mode[@name='custom'][@supported='yes']/model[@usable='unknown']"
@ -622,42 +691,65 @@ class wvmConnect(object):
return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_custom_list) return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_custom_list)
def get_hostdev_modes(self, arch, machine): def get_hostdev_modes(self, arch, machine):
"""Get available nodedev modes """ """
:param arch: architecture
:param machine:
:return. available nodedev modes
"""
def get_hostdev_list(ctx): def get_hostdev_list(ctx):
return [v.text for v in ctx.xpath("/domainCapabilities/devices/hostdev/enum[@name='mode']/value")] return [v.text for v in ctx.xpath("/domainCapabilities/devices/hostdev/enum[@name='mode']/value")]
return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_hostdev_list) return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_hostdev_list)
def get_hostdev_startup_policies(self, arch, machine): def get_hostdev_startup_policies(self, arch, machine):
"""Get available hostdev modes """ """
:param arch: architecture
:param machine:
:return: available hostdev modes
"""
def get_hostdev_list(ctx): def get_hostdev_list(ctx):
return [v.text for v in ctx.xpath("/domainCapabilities/devices/hostdev/enum[@name='startupPolicy']/value")] return [v.text for v in ctx.xpath("/domainCapabilities/devices/hostdev/enum[@name='startupPolicy']/value")]
return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_hostdev_list) return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_hostdev_list)
def get_hostdev_subsys_types(self, arch, machine): def get_hostdev_subsys_types(self, arch, machine):
"""Get available nodedev sub system types """ """
:param arch: architecture
:param machine:
:return: available nodedev sub system types
"""
def get_hostdev_list(ctx): def get_hostdev_list(ctx):
return [v.text for v in ctx.xpath("/domainCapabilities/devices/hostdev/enum[@name='subsysType']/value")] return [v.text for v in ctx.xpath("/domainCapabilities/devices/hostdev/enum[@name='subsysType']/value")]
return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_hostdev_list) return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_hostdev_list)
def get_network_models(self): def get_network_models(self):
"""Get available image filename extensions""" """
:return: network card models
"""
return ['default', 'e1000', 'virtio'] return ['default', 'e1000', 'virtio']
def get_image_formats(self): def get_image_formats(self):
"""Get available image formats""" """
:return: available image formats
"""
return ['raw', 'qcow', 'qcow2'] return ['raw', 'qcow', 'qcow2']
def get_file_extensions(self): def get_file_extensions(self):
"""Get available image filename extensions""" """
:return: available image filename extensions
"""
return ['img', 'qcow', 'qcow2'] return ['img', 'qcow', 'qcow2']
def get_video_models(self, arch, machine): def get_video_models(self, arch, machine):
""" Get available graphics video types """ """
:param arch: architecture
:param machine:
:return: available graphics video types
"""
def get_video_list(ctx): def get_video_list(ctx):
result = [] result = []
for video_enum in ctx.xpath('/domainCapabilities/devices/video/enum'): for video_enum in ctx.xpath('/domainCapabilities/devices/video/enum'):
if video_enum.xpath("@name")[0] == "modelType": if video_enum.xpath("@name")[0] == "modelType":
for values in video_enum: result.append(values.text) for values in video_enum:
result.append(values.text)
return result return result
return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_video_list) return util.get_xml_path(self.get_dom_cap_xml(arch, machine), func=get_video_list)
@ -804,7 +896,7 @@ class wvmConnect(object):
return return
loaders = self.get_os_loaders(arch, machine) loaders = self.get_os_loaders(arch, machine)
patterns = util.uefi_arch_patterns.get(arch) patterns = util.UEFI_ARCH_PATTERNS.get(arch)
for pattern in patterns: for pattern in patterns:
for path in loaders: for path in loaders:
if re.match(pattern, path): if re.match(pattern, path):
@ -820,11 +912,10 @@ class wvmConnect(object):
return "BIOS" return "BIOS"
return return
for arch, patterns in util.uefi_arch_patterns.items(): for arch, patterns in util.UEFI_ARCH_PATTERNS.items():
for pattern in patterns: for pattern in patterns:
if re.match(pattern, path): if re.match(pattern, path):
return ("UEFI %(arch)s: %(path)s" % return ("UEFI %(arch)s: %(path)s" % {"arch": arch, "path": path})
{"arch": arch, "path": path})
return "Custom: %(path)s" % {"path": path} return "Custom: %(path)s" % {"path": path}
@ -832,7 +923,7 @@ class wvmConnect(object):
""" """
Return True if we know how to setup UEFI for the passed arch Return True if we know how to setup UEFI for the passed arch
""" """
return arch in list(util.uefi_arch_patterns.keys()) return arch in list(util.UEFI_ARCH_PATTERNS.keys())
def supports_uefi_xml(self, loader_enums): def supports_uefi_xml(self, loader_enums):
""" """
@ -854,4 +945,3 @@ class wvmConnect(object):
return True return True
return False return False

View file

@ -210,7 +210,7 @@ class wvmCreate(wvmConnect):
xml += """<apic/>""" xml += """<apic/>"""
if 'pae' in caps["features"]: if 'pae' in caps["features"]:
xml += """<pae/>""" xml += """<pae/>"""
if 'yes' == firmware.get("secure", 'no'): if firmware.get("secure", 'no') == 'yes':
xml += """<smm state="on"/>""" xml += """<smm state="on"/>"""
xml += """</features>""" xml += """</features>"""

View file

@ -18,7 +18,7 @@ class wvmHostDetails(wvmConnect):
""" """
all_mem = self.wvm.getInfo()[1] * 1048576 all_mem = self.wvm.getInfo()[1] * 1048576
freemem = self.wvm.getMemoryStats(-1, 0) freemem = self.wvm.getMemoryStats(-1, 0)
if type(freemem) == dict: if isinstance(freemem, dict):
free = (freemem['buffers'] + free = (freemem['buffers'] +
freemem['free'] + freemem['free'] +
freemem['cached']) * 1024 freemem['cached']) * 1024
@ -36,7 +36,7 @@ class wvmHostDetails(wvmConnect):
prev_idle = 0 prev_idle = 0
prev_total = 0 prev_total = 0
cpu = self.wvm.getCPUStats(-1, 0) cpu = self.wvm.getCPUStats(-1, 0)
if type(cpu) == dict: if isinstance(cpu, dict):
for num in range(2): for num in range(2):
idle = self.wvm.getCPUStats(-1, 0)['idle'] idle = self.wvm.getCPUStats(-1, 0)['idle']
total = sum(self.wvm.getCPUStats(-1, 0).values()) total = sum(self.wvm.getCPUStats(-1, 0).values())
@ -66,7 +66,3 @@ class wvmHostDetails(wvmConnect):
info.append(get_xml_path(self.wvm.getSysinfo(0), func=cpu_version)) # cpu version info.append(get_xml_path(self.wvm.getSysinfo(0), func=cpu_version)) # cpu version
info.append(self.wvm.getURI()) # uri info.append(self.wvm.getURI()) # uri
return info return info

View file

@ -15,11 +15,11 @@ try:
except: except:
from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE, VIR_MIGRATE_LIVE from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE, VIR_MIGRATE_LIVE
from vrtManager import util
from xml.etree import ElementTree from xml.etree import ElementTree
from lxml import etree from lxml import etree
from datetime import datetime from datetime import datetime
from collections import OrderedDict from collections import OrderedDict
from vrtManager import util
from vrtManager.connection import wvmConnect from vrtManager.connection import wvmConnect
from vrtManager.storage import wvmStorage, wvmStorages from vrtManager.storage import wvmStorage, wvmStorages
from webvirtcloud.settings import QEMU_CONSOLE_TYPES from webvirtcloud.settings import QEMU_CONSOLE_TYPES
@ -224,19 +224,19 @@ class wvmInstance(wvmConnect):
def get_loader(self): def get_loader(self):
xml = self._XMLDesc(0) xml = self._XMLDesc(0)
loader = util.get_xml_path(xml, "/domain/os/loader") loader = util.get_xml_path(xml, "/domain/os/loader")
type = util.get_xml_path(xml, "/domain/os/loader/@type") loader_type = util.get_xml_path(xml, "/domain/os/loader/@type")
readonly = util.get_xml_path(xml, "/domain/os/loader/@readonly") readonly = util.get_xml_path(xml, "/domain/os/loader/@readonly")
return {"loader": loader, "type": type, "readonly": readonly} return {"loader": loader, "type": loader_type, "readonly": readonly}
def get_vcpus(self): def get_vcpus(self):
vcpus = OrderedDict() vcpus = OrderedDict()
tree = etree.fromstring(self._XMLDesc(0)) tree = etree.fromstring(self._XMLDesc(0))
for vcpu in tree.xpath("/domain/vcpus/vcpu"): for vcpu in tree.xpath("/domain/vcpus/vcpu"):
id = vcpu.get("id") vcpu_id = vcpu.get("id")
enabled = vcpu.get("enabled") enabled = vcpu.get("enabled")
hotplug = vcpu.get("hotpluggable") hotplug = vcpu.get("hotpluggable")
order = vcpu.get("order") order = vcpu.get("order")
vcpus[id] = {"enabled": enabled, "hotpluggable": hotplug, "order": order} vcpus[vcpu_id] = {"enabled": enabled, "hotpluggable": hotplug, "order": order}
return vcpus return vcpus
@ -325,7 +325,7 @@ class wvmInstance(wvmConnect):
# ("Calling interfaceAddresses source=%s", source) # ("Calling interfaceAddresses source=%s", source)
try: try:
return self.instance.interfaceAddresses(source) return self.instance.interfaceAddresses(source)
except Exception as e: except libvirtError as e:
# log.debug("interfaceAddresses failed: %s", str(e)) # log.debug("interfaceAddresses failed: %s", str(e))
pass pass
return {} return {}
@ -370,7 +370,7 @@ class wvmInstance(wvmConnect):
try: try:
ipv4, ipv6 = self.get_interface_addresses(mac_inst) ipv4, ipv6 = self.get_interface_addresses(mac_inst)
except: except libvirtError:
ipv4, ipv6 = None, None ipv4, ipv6 = None, None
result.append({'mac': mac_inst, result.append({'mac': mac_inst,
'nic': nic_inst, 'nic': nic_inst,
@ -644,7 +644,7 @@ class wvmInstance(wvmConnect):
xmldom = ElementTree.tostring(tree).decode() xmldom = ElementTree.tostring(tree).decode()
self._defineXML(xmldom) self._defineXML(xmldom)
def attach_disk(self, target_dev, source, target_bus='ide', disk_type='file', def attach_disk(self, target_dev, source, target_bus='ide', disk_type='file',
disk_device='disk', driver_name='qemu', driver_type='raw', disk_device='disk', driver_name='qemu', driver_type='raw',
readonly=False, shareable=False, serial=None, readonly=False, shareable=False, serial=None,
cache_mode=None, io_mode=None, discard_mode=None, detect_zeroes_mode=None): cache_mode=None, io_mode=None, discard_mode=None, detect_zeroes_mode=None):
@ -896,7 +896,7 @@ class wvmInstance(wvmConnect):
pass pass
newxml = ElementTree.tostring(root).decode() newxml = ElementTree.tostring(root).decode()
return self._defineXML(newxml) return self._defineXML(newxml)
def get_console_socket(self): def get_console_socket(self):
socket = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/@socket") socket = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/@socket")
return socket return socket
@ -1139,6 +1139,12 @@ class wvmInstance(wvmConnect):
uuid = tree.find('uuid') uuid = tree.find('uuid')
tree.remove(uuid) tree.remove(uuid)
options = {
'title': clone_data.get('clone-title', ''),
'description': clone_data.get('clone-description', ''),
}
self._set_options(tree, options)
src_nvram_path = self.get_nvram() src_nvram_path = self.get_nvram()
if src_nvram_path: if src_nvram_path:
# Change XML for nvram # Change XML for nvram
@ -1247,11 +1253,6 @@ class wvmInstance(wvmConnect):
storage = self.get_wvmStorage(pool_name) storage = self.get_wvmStorage(pool_name)
storage.clone_volume(vol_name, target_file) storage.clone_volume(vol_name, target_file)
options = {
'title': clone_data.get('clone-title', ''),
'description': clone_data.get('clone-description', ''),
}
self._set_options(tree, options)
self._defineXML(ElementTree.tostring(tree).decode()) self._defineXML(ElementTree.tostring(tree).decode())
return self.get_instance(clone_data['name']).UUIDString() return self.get_instance(clone_data['name']).UUIDString()
@ -1264,7 +1265,7 @@ class wvmInstance(wvmConnect):
net = self.get_network(source) net = self.get_network(source)
bridge_name = net.bridgeName() bridge_name = net.bridgeName()
return bridge_name return bridge_name
def add_network(self, mac_address, source, source_type='net', model='virtio', nwfilter=None): def add_network(self, mac_address, source, source_type='net', model='virtio', nwfilter=None):
bridge_name = self.get_bridge_name(source, source_type) bridge_name = self.get_bridge_name(source, source_type)
@ -1391,7 +1392,7 @@ class wvmInstance(wvmConnect):
tree.remove(option) tree.remove(option)
else: else:
if option is None: if option is None:
option = ElementTree.SubElement(tree, o) option = etree.SubElement(tree , o)
option.text = option_value option.text = option_value
def set_options(self, options): def set_options(self, options):
@ -1399,10 +1400,10 @@ class wvmInstance(wvmConnect):
Function change description, title Function change description, title
""" """
xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE) xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE)
tree = ElementTree.fromstring(xml) tree = etree.fromstring(xml)
self._set_options(tree, options) self._set_options(tree, options)
new_xml = ElementTree.tostring(tree).decode() new_xml = etree.tostring(tree).decode()
self._defineXML(new_xml) self._defineXML(new_xml)
def set_memory(self, size, flags=0): def set_memory(self, size, flags=0):
@ -1527,6 +1528,3 @@ class wvmInstance(wvmConnect):
if state == "connected": if state == "connected":
return True return True
return False return False

View file

@ -1,7 +1,8 @@
from vrtManager.connection import wvmConnect
from vrtManager import util
from xml.etree import ElementTree from xml.etree import ElementTree
from libvirt import VIR_INTERFACE_XML_INACTIVE from libvirt import VIR_INTERFACE_XML_INACTIVE
from vrtManager.connection import wvmConnect
from vrtManager import util
class wvmInterfaces(wvmConnect): class wvmInterfaces(wvmConnect):
@ -138,7 +139,7 @@ class wvmInterface(wvmConnect):
for iface in tree.findall("./bridge/"): for iface in tree.findall("./bridge/"):
address = state = speed = None address = state = speed = None
name = iface.get('name') name = iface.get('name')
type = iface.get('type') if_type = iface.get('type')
link = iface.find('link') link = iface.find('link')
if link is not None: if link is not None:
state = link.get('state') state = link.get('state')
@ -146,7 +147,7 @@ class wvmInterface(wvmConnect):
mac = iface.find('mac') mac = iface.find('mac')
if mac is not None: if mac is not None:
address = mac.get('address') address = mac.get('address')
ifaces.append({'name': name, 'type': type, 'state': state, 'speed': speed, 'mac': address}) ifaces.append({'name': name, 'type': if_type, 'state': state, 'speed': speed, 'mac': address})
return ifaces return ifaces
else: else:
return None return None

View file

@ -1,11 +1,10 @@
from vrtManager import util
from vrtManager.IPy import IP
from vrtManager.connection import wvmConnect
from lxml import etree from lxml import etree
from libvirt import VIR_NETWORK_SECTION_IP_DHCP_HOST from libvirt import VIR_NETWORK_SECTION_IP_DHCP_HOST
from libvirt import VIR_NETWORK_UPDATE_COMMAND_ADD_LAST, VIR_NETWORK_UPDATE_COMMAND_DELETE, VIR_NETWORK_UPDATE_COMMAND_MODIFY from libvirt import VIR_NETWORK_UPDATE_COMMAND_ADD_LAST, VIR_NETWORK_UPDATE_COMMAND_DELETE, VIR_NETWORK_UPDATE_COMMAND_MODIFY
from libvirt import VIR_NETWORK_UPDATE_AFFECT_LIVE, VIR_NETWORK_UPDATE_AFFECT_CONFIG from libvirt import VIR_NETWORK_UPDATE_AFFECT_LIVE, VIR_NETWORK_UPDATE_AFFECT_CONFIG
from vrtManager import util
from vrtManager.IPy import IP
from vrtManager.connection import wvmConnect
def network_size(subnet, dhcp=None): def network_size(subnet, dhcp=None):
""" """
@ -211,31 +210,31 @@ class wvmNetwork(wvmConnect):
if ipdhcp.get('family') is None: if ipdhcp.get('family') is None:
hosts = ipdhcp.findall('./dhcp/host') hosts = ipdhcp.findall('./dhcp/host')
for host in hosts: for host in hosts:
ip = host.get('ip') host_ip = host.get('ip')
mac = host.get('mac') mac = host.get('mac')
name = host.get('name', '') name = host.get('name', '')
result.append({'ip': ip, 'mac': mac, 'name': name}) result.append({'ip': host_ip, 'mac': mac, 'name': name})
return result return result
else: else:
continue continue
if family == 'ipv6': if family == 'ipv6':
hosts = tree.xpath("./ip[@family='ipv6']/dhcp/host") hosts = tree.xpath("./ip[@family='ipv6']/dhcp/host")
for host in hosts: for host in hosts:
ip = host.get('ip') host_ip = host.get('ip')
id = host.get('id') host_id = host.get('id')
name = host.get('name', '') name = host.get('name', '')
result.append({'ip': ip, 'id': id, 'name': name}) result.append({'ip': host_ip, 'id': host_id, 'name': name})
return result return result
def modify_dhcp_range(self, range_start, range_end, family='ipv4'): def modify_dhcp_range(self, range_start, range_end, family='ipv4'):
if not self.is_active(): if not self.is_active():
tree = etree.fromstring(self._XMLDesc(0)) tree = etree.fromstring(self._XMLDesc(0))
if family == 'ipv4': if family == 'ipv4':
range = tree.xpath("./ip[not(@family='ipv6')]/dhcp/range") dhcp_range = tree.xpath("./ip[not(@family='ipv6')]/dhcp/range")
if family == 'ipv6': if family == 'ipv6':
range = tree.xpath("./ip[@family='ipv6']/dhcp/range") dhcp_range = tree.xpath("./ip[@family='ipv6']/dhcp/range")
range[0].set('start', range_start) dhcp_range[0].set('start', range_start)
range[0].set('end', range_end) dhcp_range[0].set('end', range_end)
self.wvm.networkDefineXML(etree.tostring(tree).decode()) self.wvm.networkDefineXML(etree.tostring(tree).decode())
def delete_fixed_address(self, ip, family='ipv4'): def delete_fixed_address(self, ip, family='ipv4'):

View file

@ -1,5 +1,5 @@
from vrtManager.connection import wvmConnect
from xml.etree import ElementTree from xml.etree import ElementTree
from vrtManager.connection import wvmConnect
class wvmNWFilters(wvmConnect): class wvmNWFilters(wvmConnect):

View file

@ -1,8 +1,8 @@
import random import random
import lxml.etree as etree
import libvirt
import string import string
import re import re
import lxml.etree as etree
import libvirt
def is_kvm_available(xml): def is_kvm_available(xml):
@ -26,7 +26,6 @@ def randomMAC():
def randomUUID(): def randomUUID():
"""Generate a random UUID.""" """Generate a random UUID."""
u = [random.randint(0, 255) for ignore in range(0, 16)] u = [random.randint(0, 255) for ignore in range(0, 16)]
u[6] = (u[6] & 0x0F) | (4 << 4) u[6] = (u[6] & 0x0F) | (4 << 4)
u[8] = (u[8] & 0x3F) | (2 << 6) u[8] = (u[8] & 0x3F) | (2 << 6)
@ -108,7 +107,7 @@ def get_xpath(doc, path):
ret = doc.xpath(path) ret = doc.xpath(path)
if ret is not None: if ret is not None:
if type(ret) == list: if isinstance(ret, list):
if len(ret) >= 1: if len(ret) >= 1:
if hasattr(ret[0], 'text'): if hasattr(ret[0], 'text'):
result = ret[0].text result = ret[0].text
@ -137,18 +136,17 @@ def pretty_bytes(val):
def validate_uuid(val): def validate_uuid(val):
if type(val) is not str: if not isinstance(val, str):
raise ValueError("UUID must be a string.") raise ValueError("UUID must be a string.")
form = re.match("[a-fA-F0-9]{8}[-]([a-fA-F0-9]{4}[-]){3}[a-fA-F0-9]{12}$", form = re.match("[a-fA-F0-9]{8}[-]([a-fA-F0-9]{4}[-]){3}[a-fA-F0-9]{12}$", val)
val)
if form is None: if form is None:
form = re.match("[a-fA-F0-9]{32}$", val) form = re.match("[a-fA-F0-9]{32}$", val)
if form is None: if form is None:
raise ValueError( raise ValueError(
"UUID must be a 32-digit hexadecimal number. It may take " "UUID must be a 32-digit hexadecimal number. It may take "
"the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx or may " "the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx or may "
"omit hyphens altogether.") "omit hyphens altogether.")
else: # UUID had no dashes, so add them in else: # UUID had no dashes, so add them in
val = (val[0:8] + "-" + val[8:12] + "-" + val[12:16] + val = (val[0:8] + "-" + val[8:12] + "-" + val[12:16] +
@ -171,7 +169,7 @@ def validate_macaddr(val):
# Mapping of UEFI binary names to their associated architectures. We # Mapping of UEFI binary names to their associated architectures. We
# only use this info to do things automagically for the user, it shouldn't # only use this info to do things automagically for the user, it shouldn't
# validate anything the user explicitly enters. # validate anything the user explicitly enters.
uefi_arch_patterns = { UEFI_ARCH_PATTERNS = {
"i686": [ "i686": [
r".*ovmf-ia32.*", # fedora, gerd's firmware repo r".*ovmf-ia32.*", # fedora, gerd's firmware repo
], ],