diff --git a/accounts/apps.py b/accounts/apps.py index 6a2e2bd..0192800 100644 --- a/accounts/apps.py +++ b/accounts/apps.py @@ -8,7 +8,7 @@ def apply_change_password(sender, **kwargs): Depending on settings SHOW_PROFILE_EDIT_PASSWORD ''' from django.conf import settings - from django.contrib.auth.models import User, Permission + from django.contrib.auth.models import Permission, User if hasattr(settings, 'SHOW_PROFILE_EDIT_PASSWORD'): print('\033[1m! \033[92mSHOW_PROFILE_EDIT_PASSWORD is found inside settings.py\033[0m') print('\033[1m* \033[92mApplying permission can_change_password for all users\033[0m') @@ -29,8 +29,8 @@ def create_admin(sender, **kwargs): ''' Create initial admin user ''' - from django.contrib.auth.models import User from accounts.models import UserAttributes + from django.contrib.auth.models import User plan = kwargs.get('plan', []) for migration, rolled_back in plan: diff --git a/accounts/migrations/0001_initial.py b/accounts/migrations/0001_initial.py index 1990eeb..0f150f1 100644 --- a/accounts/migrations/0001_initial.py +++ b/accounts/migrations/0001_initial.py @@ -1,10 +1,12 @@ # Generated by Django 2.2.10 on 2020-01-28 07:01 -from django.conf import settings import django.core.validators -from django.db import migrations, models import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + class Migration(migrations.Migration): diff --git a/accounts/templatetags/tags_fingerprint.py b/accounts/templatetags/tags_fingerprint.py index 31f3952..83cfe14 100644 --- a/accounts/templatetags/tags_fingerprint.py +++ b/accounts/templatetags/tags_fingerprint.py @@ -1,7 +1,8 @@ -from django import template import base64 import hashlib +from django import template + register = template.Library() diff --git a/accounts/utils.py b/accounts/utils.py index af944ee..da30c0a 100644 --- a/accounts/utils.py +++ b/accounts/utils.py @@ -41,7 +41,7 @@ def validate_ssh_key(key): # data[4:str_len] must have string which matches with the typeofkey, another ssh key property. if data[4 : 4 + str_len] == typeofkey: return True - else: + else: return False diff --git a/admin/forms.py b/admin/forms.py index 1a4a226..5de4198 100644 --- a/admin/forms.py +++ b/admin/forms.py @@ -1,6 +1,6 @@ from django import forms -from django.contrib.auth.models import Group, User from django.contrib.auth.forms import ReadOnlyPasswordHashField +from django.contrib.auth.models import Group, User from django.urls import reverse_lazy from django.utils.text import format_lazy from django.utils.translation import gettext_lazy as _ @@ -76,10 +76,12 @@ class UserForm(forms.ModelForm): if self.instance.id: password = ReadOnlyPasswordHashField( label=_("Password"), - help_text=format_lazy(_("""Raw passwords are not stored, so there is no way to see - this user's password, but you can change the password using this form."""), - reverse_lazy('admin:user_update_password', - args=[self.instance.id,])) + help_text=format_lazy( + _("""Raw passwords are not stored, so there is no way to see this user's password, + but you can change the password using this form."""), + reverse_lazy('admin:user_update_password', + args=[self.instance.id,]) + ) ) self.fields['Password'] = password diff --git a/computes/urls.py b/computes/urls.py index 08248de..6e43695 100644 --- a/computes/urls.py +++ b/computes/urls.py @@ -1,7 +1,6 @@ from secrets.views import secrets from django.urls import include, path - # from instances.views import create_instance, create_instance_select_type from interfaces.views import interface, interfaces from networks.views import network, networks diff --git a/computes/validators.py b/computes/validators.py index e58dfea..fba59b5 100644 --- a/computes/validators.py +++ b/computes/validators.py @@ -1,8 +1,9 @@ -from django.core.exceptions import ValidationError - -from django.utils.translation import gettext_lazy as _ import re +from django.core.exceptions import ValidationError +from django.utils.translation import gettext_lazy as _ + + have_symbol = re.compile('[^a-zA-Z0-9._-]+') wrong_ip = re.compile('^0.|^255.') wrong_name = re.compile('[^a-zA-Z0-9._-]+') diff --git a/computes/views.py b/computes/views.py index a3ce691..53d42a4 100644 --- a/computes/views.py +++ b/computes/views.py @@ -1,13 +1,12 @@ import json from django.contrib import messages -from django.http import HttpResponse, HttpResponseRedirect -from django.shortcuts import get_object_or_404, redirect, render, reverse +from django.http import HttpResponse +from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse from django.utils import timezone from libvirt import libvirtError -from accounts.models import UserInstance from admin.decorators import superuser_only from computes.forms import SocketComputeForm, SshComputeForm, TcpComputeForm, TlsComputeForm from computes.models import Compute diff --git a/conf/runit/secret_generator.py b/conf/runit/secret_generator.py index 2a5a8dc..e22ca7b 100644 --- a/conf/runit/secret_generator.py +++ b/conf/runit/secret_generator.py @@ -1,4 +1,5 @@ -import random, string +import random +import string haystack = string.ascii_letters + string.digits + string.punctuation print(''.join([random.SystemRandom().choice(haystack.replace('/', '').replace('\'', '').replace('\"', '')) for _ in range(50)])) diff --git a/console/sshtunnels.py b/console/sshtunnels.py index 336febd..6ad9dde 100644 --- a/console/sshtunnels.py +++ b/console/sshtunnels.py @@ -4,13 +4,14 @@ # See the COPYING file in the top-level directory. import functools +import logging as log import os import queue -import socket import signal +import socket import threading -import logging as log + class _TunnelScheduler(object): diff --git a/console/views.py b/console/views.py index d12df26..e36895a 100644 --- a/console/views.py +++ b/console/views.py @@ -6,7 +6,11 @@ from libvirt import libvirtError from appsettings.settings import app_settings from instances.models import Instance from vrtManager.instance import wvmInstance -from webvirtcloud.settings import WS_PUBLIC_HOST, WS_PUBLIC_PATH, WS_PUBLIC_PORT +from webvirtcloud.settings import ( + WS_PUBLIC_HOST, + WS_PUBLIC_PATH, + WS_PUBLIC_PORT +) def console(request): @@ -57,7 +61,7 @@ def console(request): if console_type == "vnc" or console_type == "spice": console_page = "console-" + console_type + "-" + view_type + ".html" response = render(request, console_page, locals()) - else: + else: if console_type is None: console_error = "Fail to get console. Please check the console configuration of your VM." else: diff --git a/datasource/views.py b/datasource/views.py index 519f625..1a18ff5 100644 --- a/datasource/views.py +++ b/datasource/views.py @@ -1,8 +1,10 @@ import json 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 diff --git a/instances/apps.py b/instances/apps.py index 3b5c07d..49983ac 100644 --- a/instances/apps.py +++ b/instances/apps.py @@ -25,8 +25,8 @@ def apply_passwordless_console(sender, **kwargs): ''' Apply new passwordless_console permission for all users ''' - from django.contrib.auth.models import Permission from django.contrib.auth import get_user_model + from django.contrib.auth.models import Permission User = get_user_model() plan = kwargs.get('plan', []) for migration, rolled_back in plan: diff --git a/instances/migrations/0001_initial.py b/instances/migrations/0001_initial.py index e27f7aa..6b64b27 100644 --- a/instances/migrations/0001_initial.py +++ b/instances/migrations/0001_initial.py @@ -1,7 +1,6 @@ # Generated by Django 2.2.10 on 2020-01-28 07:01 - -from django.db import migrations, models import django.db.models.deletion +from django.db import migrations, models class Migration(migrations.Migration): diff --git a/instances/migrations/0006_addFlavors.py b/instances/migrations/0006_addFlavors.py index b1af99d..661014b 100644 --- a/instances/migrations/0006_addFlavors.py +++ b/instances/migrations/0006_addFlavors.py @@ -32,4 +32,5 @@ class Migration(migrations.Migration): operations = [ migrations.RunPython(add_flavors, del_flavors), - ] \ No newline at end of file + ] + \ No newline at end of file diff --git a/instances/templatetags/tags_active.py b/instances/templatetags/tags_active.py index 5af5248..2745147 100644 --- a/instances/templatetags/tags_active.py +++ b/instances/templatetags/tags_active.py @@ -1,6 +1,7 @@ -from django import template import re +from django import template + register = template.Library() diff --git a/instances/tests.py b/instances/tests.py index 5c70322..20e1bfc 100644 --- a/instances/tests.py +++ b/instances/tests.py @@ -8,12 +8,11 @@ from django.contrib.auth.models import Permission from django.http.response import Http404 from django.shortcuts import reverse from django.test import TestCase +from instances.views import instance from libvirt import VIR_DOMAIN_UNDEFINE_NVRAM from vrtManager.create import wvmCreate from vrtManager.util import randomUUID -from instances.views import instance - from .models import Flavor, Instance from .utils import refr diff --git a/instances/views.py b/instances/views.py index 6b9dbe1..7b0e5c8 100644 --- a/instances/views.py +++ b/instances/views.py @@ -19,6 +19,7 @@ from django.http import Http404, HttpResponse, JsonResponse from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse from django.utils.translation import gettext_lazy as _ +from instances.models import Instance from libvirt import VIR_DOMAIN_UNDEFINE_KEEP_NVRAM, VIR_DOMAIN_UNDEFINE_NVRAM, libvirtError from logs.views import addlogmsg from vrtManager import util @@ -27,8 +28,6 @@ from vrtManager.instance import wvmInstances from vrtManager.storage import wvmStorage from vrtManager.util import randomPasswd -from instances.models import Instance - from . import utils from .forms import ConsoleForm, FlavorForm, NewVMForm from .models import Flavor @@ -438,7 +437,7 @@ def resizevm_cpu(request, pk): cur_vcpu = new_cur_vcpu vcpu = new_vcpu instance.proxy.resize_cpu(cur_vcpu, vcpu) - msg = _("CPU is resized: %(old)s to %(new)s") % {"old": cur_vcpu,"new": vcpu} + msg = _("CPU is resized: %(old)s to %(new)s") % {"old": cur_vcpu, "new": vcpu} addlogmsg(request.user.username, instance.name, msg) messages.success(request, msg) return redirect(reverse("instances:instance", args=[instance.id]) + "#resize") @@ -951,7 +950,7 @@ def change_network(request, pk): @superuser_only def add_network(request, pk): instance = get_instance(request.user, pk) - + mac = request.POST.get("add-net-mac") nwfilter = request.POST.get("add-net-nwfilter") (source, source_type) = utils.get_network_tuple(request.POST.get("add-net-network")) @@ -1181,8 +1180,8 @@ def update_console(request, pk): instance.proxy.set_console_keymap("") else: instance.proxy.set_console_keymap(form.cleaned_data["keymap"]) - msg = _("Set VNC keymap") - + + msg = _("Set VNC keymap") addlogmsg(request.user.username, instance.name, msg) if "type" in form.changed_data: @@ -1287,7 +1286,7 @@ def create_instance_select_type(request, compute_id): xml = request.POST.get("dom_xml", "") try: name = util.get_xml_path(xml, "/domain/name") - except util.etree.Error as err: + except util.etree.Error: name = None if name in instances: error_msg = _("A virtual machine with this name already exists") diff --git a/interfaces/forms.py b/interfaces/forms.py index 4490d0b..c19ffda 100644 --- a/interfaces/forms.py +++ b/interfaces/forms.py @@ -1,4 +1,5 @@ import re + from django import forms from django.utils.translation import gettext_lazy as _ diff --git a/logs/models.py b/logs/models.py index d45c056..4be72b6 100644 --- a/logs/models.py +++ b/logs/models.py @@ -1,12 +1,12 @@ -from django.db.models import Model, CharField, DateTimeField from django.utils.translation import gettext_lazy as _ +from django.db.models import Model, CharField, DateTimeField class Logs(Model): - user = CharField(_('user'), max_length=50) - instance = CharField(_('instance'), max_length=50) - message = CharField(_('message'), max_length=255) - date = DateTimeField(_('date'), auto_now=True) + user = CharField(_("user"), max_length=50) + instance = CharField(_("instance"), max_length=50) + message = CharField(_("message"), max_length=255) + date = DateTimeField(_("date"), auto_now=True) def __str__(self): return self.instance diff --git a/logs/urls.py b/logs/urls.py index 41618ae..2e8ca5a 100644 --- a/logs/urls.py +++ b/logs/urls.py @@ -1,6 +1,7 @@ from django.urls import path + from . import views urlpatterns = [ - path('vm_logs//', views.vm_logs, name='vm_logs'), + path("vm_logs//", views.vm_logs, name="vm_logs"), ] diff --git a/logs/views.py b/logs/views.py index 7e98221..0f94940 100644 --- a/logs/views.py +++ b/logs/views.py @@ -1,8 +1,6 @@ import json -from django.http import HttpResponse, HttpResponseRedirect -from django.shortcuts import render -from django.urls import reverse +from django.http import HttpResponse from admin.decorators import superuser_only from instances.models import Instance @@ -29,14 +27,14 @@ def vm_logs(request, vname): """ vm = Instance.objects.get(name=vname) - logs_ = Logs.objects.filter(instance=vm.name, date__gte=vm.created).order_by('-date') + logs_ = Logs.objects.filter(instance=vm.name, date__gte=vm.created).order_by("-date") logs = [] for l in logs_: log = dict() - log['user'] = l.user - log['instance'] = l.instance - log['message'] = l.message - log['date'] = l.date.strftime('%x %X') + log["user"] = l.user + log["instance"] = l.instance + log["message"] = l.message + log["date"] = l.date.strftime("%x %X") logs.append(log) return HttpResponse(json.dumps(logs)) diff --git a/networks/forms.py b/networks/forms.py index 6b9189f..fe2fcd3 100644 --- a/networks/forms.py +++ b/networks/forms.py @@ -1,4 +1,5 @@ import re + from django import forms from django.utils.translation import gettext_lazy as _ diff --git a/networks/views.py b/networks/views.py index 6f48662..f40a395 100644 --- a/networks/views.py +++ b/networks/views.py @@ -239,7 +239,8 @@ def network(request, compute_id, pool): if conn.is_active(): messages.success( request, - _("%(qos_dir)s QoS is deleted. Network XML is changed. Stop and start network to activate new config") % {"qos_dir": qos_dir.capitalize()} + _("%(qos_dir)s QoS is deleted. Network XML is changed. \ + Stop and start network to activate new config") % {"qos_dir": qos_dir.capitalize()} ) else: messages.success(request, _("%(qos_dir)s QoS is deleted") % {"qos_dir": qos_dir.capitalize()}) diff --git a/nwfilters/apps.py b/nwfilters/apps.py index 11475c5..496ed18 100644 --- a/nwfilters/apps.py +++ b/nwfilters/apps.py @@ -5,4 +5,4 @@ from django.apps import AppConfig class NwfiltersConfig(AppConfig): - name = 'nwfilters' + name = "nwfilters" diff --git a/nwfilters/views.py b/nwfilters/views.py index 52f6fc6..7cb690d 100644 --- a/nwfilters/views.py +++ b/nwfilters/views.py @@ -25,6 +25,9 @@ def nwfilters(request, compute_id): try: conn = wvmNWFilters(compute.hostname, compute.login, compute.password, compute.type) + for nwf in conn.get_nwfilters(): + nwfilters_all.append(conn.get_nwfilter_info(nwf)) + if request.method == "POST": if "create_nwfilter" in request.POST: xml = request.POST.get("nwfilter_xml", "") @@ -36,11 +39,11 @@ def nwfilters(request, compute_id): except util.etree.ParseError: name = None - for nwf in nwfilters: - if name == nwf.name(): + for nwf in nwfilters_all: + if name == nwf["name"]: error_msg = _("A network filter with this name already exists") raise Exception(error_msg) - if uuid == nwf.UUIDString(): + if uuid == nwf["uuid"]: error_msg = _("A network filter with this UUID already exists") raise Exception(error_msg) else: @@ -90,9 +93,6 @@ def nwfilters(request, compute_id): msg = _("Cloning NWFilter %(name)s as %(clone)s") % {"name":name, "clone": cln_name} addlogmsg(request.user.username, compute.hostname, msg) - for nwf in conn.get_nwfilters(): - nwfilters_all.append(conn.get_nwfilter_info(nwf)) - conn.close() except libvirtError as lib_err: messages.error(request, lib_err) diff --git a/storages/forms.py b/storages/forms.py index f2fd89b..64dcd3c 100644 --- a/storages/forms.py +++ b/storages/forms.py @@ -1,4 +1,5 @@ import re + from django import forms from django.utils.translation import gettext_lazy as _ diff --git a/storages/views.py b/storages/views.py index 732e332..cc88179 100644 --- a/storages/views.py +++ b/storages/views.py @@ -45,11 +45,7 @@ def storages(request, compute_id): msg = _("You need create secret for pool") messages.error(request, msg) errors = True - if ( - not data["ceph_pool"] - and not data["ceph_host"] - and not data["ceph_user"] - ): + if not data["ceph_pool"] and not data["ceph_host"] and not data["ceph_user"]: msg = _("You need input all fields for creating ceph pool") messages.error(request, msg) errors = True @@ -73,12 +69,8 @@ def storages(request, compute_id): data["target"], ) else: - conn.create_storage( - data["stg_type"], data["name"], data["source"], data["target"] - ) - return HttpResponseRedirect( - reverse("storage", args=[compute_id, data["name"]]) - ) + conn.create_storage(data["stg_type"], data["name"], data["source"], data["target"]) + return HttpResponseRedirect(reverse("storage", args=[compute_id, data["name"]])) else: for msg_err in form.errors.values(): messages.error(request, msg_err.as_text()) @@ -159,7 +151,7 @@ def storage(request, compute_id, pool): messages.error(request, error_msg) else: handle_uploaded_file(path, request.FILES["file"]) - messages.success(request, _("ISO: %(file)s is uploaded.") % {"file": request.FILES['file']}) + messages.success(request, _("ISO: %(file)s is uploaded.") % {"file": request.FILES["file"]}) return HttpResponseRedirect(request.get_full_path()) if "cln_volume" in request.POST: form = CloneImage(request.POST) @@ -179,7 +171,8 @@ def storage(request, compute_id, pool): try: name = conn.clone_volume(data["image"], data["name"], format, meta_prealloc) messages.success( - request, _("%(image)s image cloned as %(clone)s successfully") % {"image": data['image'], "name": name} + request, + _("%(image)s image cloned as %(clone)s successfully") % {"image": data["image"], "name": name}, ) return HttpResponseRedirect(request.get_full_path()) except libvirtError as lib_err: @@ -199,7 +192,7 @@ def create_volume(request, compute_id, pool): :param request: :param compute_id: compute id :param pool: pool name - :return: + :return: """ compute = get_object_or_404(Compute, pk=compute_id) meta_prealloc = False @@ -225,7 +218,7 @@ def create_volume(request, compute_id, pool): disk_owner_uid, disk_owner_gid, ) - messages.success(request, _("Image file %(name)s is created successfully") % {"name":name}) + messages.success(request, _("Image file %(name)s is created successfully") % {"name": name}) else: for msg_err in form.errors.values(): messages.error(request, msg_err.as_text()) diff --git a/vrtManager/IPy.py b/vrtManager/IPy.py index b157f3d..163010b 100644 --- a/vrtManager/IPy.py +++ b/vrtManager/IPy.py @@ -6,7 +6,7 @@ Further Information might be available at: https://github.com/haypo/python-ipy """ -__version__ = '1.00' +__version__ = "1.00" import bisect import collections @@ -17,16 +17,16 @@ import types # this should include www.iana.org/assignments/ipv4-address-space # and www.iana.org/assignments/multicast-addresses IPv4ranges = { - '0': 'PUBLIC', # fall back - '00000000': 'PRIVATE', # 0/8 - '00001010': 'PRIVATE', # 10/8 - '0110010001': 'CARRIER_GRADE_NAT', # 100.64/10 - '01111111': 'LOOPBACK', # 127.0/8 - '1': 'PUBLIC', # fall back - '1010100111111110': 'PRIVATE', # 169.254/16 - '101011000001': 'PRIVATE', # 172.16/12 - '1100000010101000': 'PRIVATE', # 192.168/16 - '111': 'RESERVED', # 224/3 + "0": "PUBLIC", # fall back + "00000000": "PRIVATE", # 0/8 + "00001010": "PRIVATE", # 10/8 + "0110010001": "CARRIER_GRADE_NAT", # 100.64/10 + "01111111": "LOOPBACK", # 127.0/8 + "1": "PUBLIC", # fall back + "1010100111111110": "PRIVATE", # 169.254/16 + "101011000001": "PRIVATE", # 172.16/12 + "1100000010101000": "PRIVATE", # 192.168/16 + "111": "RESERVED", # 224/3 } # Definition of the Ranges for IPv6 IPs @@ -34,92 +34,92 @@ IPv4ranges = { # http://www.iana.org/assignments/ipv6-unicast-address-assignments/ # http://www.iana.org/assignments/ipv6-multicast-addresses/ IPv6ranges = { - '00000000': 'RESERVED', # ::/8 - '0' * 96: 'RESERVED', # ::/96 Formerly IPV4COMP [RFC4291] - '0' * 128: 'UNSPECIFIED', # ::/128 - '0' * 127 + '1': 'LOOPBACK', # ::1/128 - '0' * 80 + '1' * 16: 'IPV4MAP', # ::ffff:0:0/96 - '00000000011001001111111110011011' + '0' * 64: 'WKP46TRANS', # 0064:ff9b::/96 Well-Known-Prefix [RFC6052] - '00000001': 'UNASSIGNED', # 0100::/8 - '0000001': 'RESERVED', # 0200::/7 Formerly NSAP [RFC4048] - '0000010': 'RESERVED', # 0400::/7 Formerly IPX [RFC3513] - '0000011': 'RESERVED', # 0600::/7 - '00001': 'RESERVED', # 0800::/5 - '0001': 'RESERVED', # 1000::/4 - '001': 'GLOBAL-UNICAST', # 2000::/3 [RFC4291] - '00100000000000010000000': 'SPECIALPURPOSE', # 2001::/23 [RFC4773] - '00100000000000010000000000000000': 'TEREDO', # 2001::/32 [RFC4380] - '00100000000000010000000000000010' + '0' * 16: 'BMWG', # 2001:0002::/48 Benchmarking [RFC5180] - '0010000000000001000000000001': 'ORCHID', # 2001:0010::/28 (Temp until 2014-03-21) [RFC4843] - '00100000000000010000001': 'ALLOCATED APNIC', # 2001:0200::/23 - '00100000000000010000010': 'ALLOCATED ARIN', # 2001:0400::/23 - '00100000000000010000011': 'ALLOCATED RIPE NCC', # 2001:0600::/23 - '00100000000000010000100': 'ALLOCATED RIPE NCC', # 2001:0800::/23 - '00100000000000010000101': 'ALLOCATED RIPE NCC', # 2001:0a00::/23 - '00100000000000010000110': 'ALLOCATED APNIC', # 2001:0c00::/23 - '00100000000000010000110110111000': 'DOCUMENTATION', # 2001:0db8::/32 [RFC3849] - '00100000000000010000111': 'ALLOCATED APNIC', # 2001:0e00::/23 - '00100000000000010001001': 'ALLOCATED LACNIC', # 2001:1200::/23 - '00100000000000010001010': 'ALLOCATED RIPE NCC', # 2001:1400::/23 - '00100000000000010001011': 'ALLOCATED RIPE NCC', # 2001:1600::/23 - '00100000000000010001100': 'ALLOCATED ARIN', # 2001:1800::/23 - '00100000000000010001101': 'ALLOCATED RIPE NCC', # 2001:1a00::/23 - '0010000000000001000111': 'ALLOCATED RIPE NCC', # 2001:1c00::/22 - '00100000000000010010': 'ALLOCATED RIPE NCC', # 2001:2000::/20 - '001000000000000100110': 'ALLOCATED RIPE NCC', # 2001:3000::/21 - '0010000000000001001110': 'ALLOCATED RIPE NCC', # 2001:3800::/22 - '0010000000000001001111': 'RESERVED', # 2001:3c00::/22 Possible future allocation to RIPE NCC - '00100000000000010100000': 'ALLOCATED RIPE NCC', # 2001:4000::/23 - '00100000000000010100001': 'ALLOCATED AFRINIC', # 2001:4200::/23 - '00100000000000010100010': 'ALLOCATED APNIC', # 2001:4400::/23 - '00100000000000010100011': 'ALLOCATED RIPE NCC', # 2001:4600::/23 - '00100000000000010100100': 'ALLOCATED ARIN', # 2001:4800::/23 - '00100000000000010100101': 'ALLOCATED RIPE NCC', # 2001:4a00::/23 - '00100000000000010100110': 'ALLOCATED RIPE NCC', # 2001:4c00::/23 - '00100000000000010101': 'ALLOCATED RIPE NCC', # 2001:5000::/20 - '0010000000000001100': 'ALLOCATED APNIC', # 2001:8000::/19 - '00100000000000011010': 'ALLOCATED APNIC', # 2001:a000::/20 - '00100000000000011011': 'ALLOCATED APNIC', # 2001:b000::/20 - '0010000000000010': '6TO4', # 2002::/16 "6to4" [RFC3056] - '001000000000001100': 'ALLOCATED RIPE NCC', # 2003::/18 - '001001000000': 'ALLOCATED APNIC', # 2400::/12 - '001001100000': 'ALLOCATED ARIN', # 2600::/12 - '00100110000100000000000': 'ALLOCATED ARIN', # 2610::/23 - '00100110001000000000000': 'ALLOCATED ARIN', # 2620::/23 - '001010000000': 'ALLOCATED LACNIC', # 2800::/12 - '001010100000': 'ALLOCATED RIPE NCC', # 2a00::/12 - '001011000000': 'ALLOCATED AFRINIC', # 2c00::/12 - '00101101': 'RESERVED', # 2d00::/8 - '0010111': 'RESERVED', # 2e00::/7 - '0011': 'RESERVED', # 3000::/4 - '010': 'RESERVED', # 4000::/3 - '011': 'RESERVED', # 6000::/3 - '100': 'RESERVED', # 8000::/3 - '101': 'RESERVED', # a000::/3 - '110': 'RESERVED', # c000::/3 - '1110': 'RESERVED', # e000::/4 - '11110': 'RESERVED', # f000::/5 - '111110': 'RESERVED', # f800::/6 - '1111110': 'ULA', # fc00::/7 [RFC4193] - '111111100': 'RESERVED', # fe00::/9 - '1111111010': 'LINKLOCAL', # fe80::/10 - '1111111011': 'RESERVED', # fec0::/10 Formerly SITELOCAL [RFC4291] - '11111111': 'MULTICAST', # ff00::/8 - '1111111100000001': 'NODE-LOCAL MULTICAST', # ff01::/16 - '1111111100000010': 'LINK-LOCAL MULTICAST', # ff02::/16 - '1111111100000100': 'ADMIN-LOCAL MULTICAST', # ff04::/16 - '1111111100000101': 'SITE-LOCAL MULTICAST', # ff05::/16 - '1111111100001000': 'ORG-LOCAL MULTICAST', # ff08::/16 - '1111111100001110': 'GLOBAL MULTICAST', # ff0e::/16 - '1111111100001111': 'RESERVED MULTICAST', # ff0f::/16 - '111111110011': 'PREFIX-BASED MULTICAST', # ff30::/12 [RFC3306] - '111111110111': 'RP-EMBEDDED MULTICAST', # ff70::/12 [RFC3956] + "00000000": "RESERVED", # ::/8 + "0" * 96: "RESERVED", # ::/96 Formerly IPV4COMP [RFC4291] + "0" * 128: "UNSPECIFIED", # ::/128 + "0" * 127 + "1": "LOOPBACK", # ::1/128 + "0" * 80 + "1" * 16: "IPV4MAP", # ::ffff:0:0/96 + "00000000011001001111111110011011" + "0" * 64: "WKP46TRANS", # 0064:ff9b::/96 Well-Known-Prefix [RFC6052] + "00000001": "UNASSIGNED", # 0100::/8 + "0000001": "RESERVED", # 0200::/7 Formerly NSAP [RFC4048] + "0000010": "RESERVED", # 0400::/7 Formerly IPX [RFC3513] + "0000011": "RESERVED", # 0600::/7 + "00001": "RESERVED", # 0800::/5 + "0001": "RESERVED", # 1000::/4 + "001": "GLOBAL-UNICAST", # 2000::/3 [RFC4291] + "00100000000000010000000": "SPECIALPURPOSE", # 2001::/23 [RFC4773] + "00100000000000010000000000000000": "TEREDO", # 2001::/32 [RFC4380] + "00100000000000010000000000000010" + "0" * 16: "BMWG", # 2001:0002::/48 Benchmarking [RFC5180] + "0010000000000001000000000001": "ORCHID", # 2001:0010::/28 (Temp until 2014-03-21) [RFC4843] + "00100000000000010000001": "ALLOCATED APNIC", # 2001:0200::/23 + "00100000000000010000010": "ALLOCATED ARIN", # 2001:0400::/23 + "00100000000000010000011": "ALLOCATED RIPE NCC", # 2001:0600::/23 + "00100000000000010000100": "ALLOCATED RIPE NCC", # 2001:0800::/23 + "00100000000000010000101": "ALLOCATED RIPE NCC", # 2001:0a00::/23 + "00100000000000010000110": "ALLOCATED APNIC", # 2001:0c00::/23 + "00100000000000010000110110111000": "DOCUMENTATION", # 2001:0db8::/32 [RFC3849] + "00100000000000010000111": "ALLOCATED APNIC", # 2001:0e00::/23 + "00100000000000010001001": "ALLOCATED LACNIC", # 2001:1200::/23 + "00100000000000010001010": "ALLOCATED RIPE NCC", # 2001:1400::/23 + "00100000000000010001011": "ALLOCATED RIPE NCC", # 2001:1600::/23 + "00100000000000010001100": "ALLOCATED ARIN", # 2001:1800::/23 + "00100000000000010001101": "ALLOCATED RIPE NCC", # 2001:1a00::/23 + "0010000000000001000111": "ALLOCATED RIPE NCC", # 2001:1c00::/22 + "00100000000000010010": "ALLOCATED RIPE NCC", # 2001:2000::/20 + "001000000000000100110": "ALLOCATED RIPE NCC", # 2001:3000::/21 + "0010000000000001001110": "ALLOCATED RIPE NCC", # 2001:3800::/22 + "0010000000000001001111": "RESERVED", # 2001:3c00::/22 Possible future allocation to RIPE NCC + "00100000000000010100000": "ALLOCATED RIPE NCC", # 2001:4000::/23 + "00100000000000010100001": "ALLOCATED AFRINIC", # 2001:4200::/23 + "00100000000000010100010": "ALLOCATED APNIC", # 2001:4400::/23 + "00100000000000010100011": "ALLOCATED RIPE NCC", # 2001:4600::/23 + "00100000000000010100100": "ALLOCATED ARIN", # 2001:4800::/23 + "00100000000000010100101": "ALLOCATED RIPE NCC", # 2001:4a00::/23 + "00100000000000010100110": "ALLOCATED RIPE NCC", # 2001:4c00::/23 + "00100000000000010101": "ALLOCATED RIPE NCC", # 2001:5000::/20 + "0010000000000001100": "ALLOCATED APNIC", # 2001:8000::/19 + "00100000000000011010": "ALLOCATED APNIC", # 2001:a000::/20 + "00100000000000011011": "ALLOCATED APNIC", # 2001:b000::/20 + "0010000000000010": "6TO4", # 2002::/16 "6to4" [RFC3056] + "001000000000001100": "ALLOCATED RIPE NCC", # 2003::/18 + "001001000000": "ALLOCATED APNIC", # 2400::/12 + "001001100000": "ALLOCATED ARIN", # 2600::/12 + "00100110000100000000000": "ALLOCATED ARIN", # 2610::/23 + "00100110001000000000000": "ALLOCATED ARIN", # 2620::/23 + "001010000000": "ALLOCATED LACNIC", # 2800::/12 + "001010100000": "ALLOCATED RIPE NCC", # 2a00::/12 + "001011000000": "ALLOCATED AFRINIC", # 2c00::/12 + "00101101": "RESERVED", # 2d00::/8 + "0010111": "RESERVED", # 2e00::/7 + "0011": "RESERVED", # 3000::/4 + "010": "RESERVED", # 4000::/3 + "011": "RESERVED", # 6000::/3 + "100": "RESERVED", # 8000::/3 + "101": "RESERVED", # a000::/3 + "110": "RESERVED", # c000::/3 + "1110": "RESERVED", # e000::/4 + "11110": "RESERVED", # f000::/5 + "111110": "RESERVED", # f800::/6 + "1111110": "ULA", # fc00::/7 [RFC4193] + "111111100": "RESERVED", # fe00::/9 + "1111111010": "LINKLOCAL", # fe80::/10 + "1111111011": "RESERVED", # fec0::/10 Formerly SITELOCAL [RFC4291] + "11111111": "MULTICAST", # ff00::/8 + "1111111100000001": "NODE-LOCAL MULTICAST", # ff01::/16 + "1111111100000010": "LINK-LOCAL MULTICAST", # ff02::/16 + "1111111100000100": "ADMIN-LOCAL MULTICAST", # ff04::/16 + "1111111100000101": "SITE-LOCAL MULTICAST", # ff05::/16 + "1111111100001000": "ORG-LOCAL MULTICAST", # ff08::/16 + "1111111100001110": "GLOBAL MULTICAST", # ff0e::/16 + "1111111100001111": "RESERVED MULTICAST", # ff0f::/16 + "111111110011": "PREFIX-BASED MULTICAST", # ff30::/12 [RFC3306] + "111111110111": "RP-EMBEDDED MULTICAST", # ff70::/12 [RFC3956] } -MAX_IPV4_ADDRESS = 0xffffffff -MAX_IPV6_ADDRESS = 0xffffffffffffffffffffffffffffffff -IPV6_TEST_MAP = 0xffffffffffffffffffffffff00000000 -IPV6_MAP_MASK = 0x00000000000000000000ffff00000000 +MAX_IPV4_ADDRESS = 0xFFFFFFFF +MAX_IPV6_ADDRESS = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +IPV6_TEST_MAP = 0xFFFFFFFFFFFFFFFFFFFFFFFF00000000 +IPV6_MAP_MASK = 0x00000000000000000000FFFF00000000 if sys.version_info >= (3,): INT_TYPES = (int,) @@ -202,7 +202,7 @@ class IPint(object): elif isinstance(data, STR_TYPES): # TODO: refactor me! # splitting of a string into IP and prefixlen et. al. - x = data.split('-') + x = data.split("-") if len(x) == 2: # a.b.c.0-a.b.c.255 specification ? (ip, last) = x @@ -219,10 +219,10 @@ class IPint(object): # make sure the broadcast is the same as the last ip # otherwise it will return /16 for something like: # 192.168.0.0-192.168.191.255 - if IP('%s/%s' % (ip, 32 - netbits)).broadcast().int() != last: + if IP("%s/%s" % (ip, 32 - netbits)).broadcast().int() != last: raise ValueError("the range %s is not on a network boundary." % data) elif len(x) == 1: - x = data.split('/') + x = data.split("/") # if no prefix is given use defaults if len(x) == 1: ip = x[0] @@ -231,7 +231,7 @@ class IPint(object): raise ValueError("only one '/' allowed in IP Address") else: (ip, prefixlen) = x - if prefixlen.find('.') != -1: + if prefixlen.find(".") != -1: # check if the user might have used a netmask like # a.b.c.d/255.255.255.0 (netmask, vers) = parseAddress(prefixlen) @@ -255,8 +255,7 @@ class IPint(object): if make_net: self.ip = self.ip & _prefixlenToNetmask(self._prefixlen, self._ipversion) - if not _checkNetaddrWorksWithPrefixlen(self.ip, - self._prefixlen, self._ipversion): + if not _checkNetaddrWorksWithPrefixlen(self.ip, self._prefixlen, self._ipversion): raise ValueError("%s has invalid prefix length (%s)" % (repr(self), self._prefixlen)) else: raise TypeError("Unsupported data type: %s" % type(data)) @@ -314,8 +313,7 @@ class IPint(object): want == 3 -lastip 1.2.3.0-1.2.3.255 """ - if (self._ipversion == 4 and self._prefixlen == 32) or \ - (self._ipversion == 6 and self._prefixlen == 128): + if (self._ipversion == 4 and self._prefixlen == 32) or (self._ipversion == 6 and self._prefixlen == 128): if self.NoPrefixForSingleIp: want = 0 if want is None: @@ -335,7 +333,7 @@ class IPint(object): # default return "/%d" % (self._prefixlen) else: - return '' + return "" # We have different flavours to convert to: # strFullsize 127.0.0.1 2001:0658:022a:cafe:0200:c0ff:fe8d:08fa @@ -357,7 +355,7 @@ class IPint(object): if self.WantPrefixLen is None and wantprefixlen is None: wantprefixlen = 0 ret = _intToBin(self.ip) - return '0' * (bits - len(ret)) + ret + self._printPrefix(wantprefixlen) + return "0" * (bits - len(ret)) + ret + self._printPrefix(wantprefixlen) def strCompressed(self, wantprefixlen=None): """Return a string representation in compressed format using '::' Notation. @@ -376,12 +374,12 @@ class IPint(object): if self._ipversion == 4: return self.strFullsize(wantprefixlen) else: - if self.ip >> 32 == 0xffff: + if self.ip >> 32 == 0xFFFF: ipv4 = intToIp(self.ip & MAX_IPV4_ADDRESS, 4) text = "::ffff:" + ipv4 + self._printPrefix(wantprefixlen) return text # find the longest sequence of '0' - hextets = [int(x, 16) for x in self.strFullsize(0).split(':')] + hextets = [int(x, 16) for x in self.strFullsize(0).split(":")] # every element of followingzeros will contain the number of zeros # following the corresponding element of hextets followingzeros = [0] * 8 @@ -392,15 +390,15 @@ class IPint(object): if max(followingzeros) > 1: # genererate string with the longest number of zeros cut out # now we need hextets as strings - hextets = [x for x in self.strNormal(0).split(':')] - while compressionpos < len(hextets) and hextets[compressionpos] == '0': - del (hextets[compressionpos]) - hextets.insert(compressionpos, '') + hextets = [x for x in self.strNormal(0).split(":")] + while compressionpos < len(hextets) and hextets[compressionpos] == "0": + del hextets[compressionpos] + hextets.insert(compressionpos, "") if compressionpos + 1 >= len(hextets): - hextets.append('') + hextets.append("") if compressionpos == 0: - hextets = [''] + hextets - return ':'.join(hextets) + self._printPrefix(wantprefixlen) + hextets = [""] + hextets + return ":".join(hextets) + self._printPrefix(wantprefixlen) else: return self.strNormal(0) + self._printPrefix(wantprefixlen) @@ -419,7 +417,7 @@ class IPint(object): if self._ipversion == 4: ret = self.strFullsize(0) elif self._ipversion == 6: - ret = ':'.join(["%x" % x for x in [int(x, 16) for x in self.strFullsize(0).split(':')]]) + ret = ":".join(["%x" % x for x in [int(x, 16) for x in self.strFullsize(0).split(":")]]) else: raise ValueError("only IPv4 and IPv6 supported") @@ -451,7 +449,7 @@ class IPint(object): if self.WantPrefixLen is None and wantprefixlen is None: wantprefixlen = 0 - x = '0x%x' % self.ip + x = "0x%x" % self.ip return x + self._printPrefix(wantprefixlen) def strDec(self, wantprefixlen=None): @@ -466,7 +464,7 @@ class IPint(object): if self.WantPrefixLen is None and wantprefixlen is None: wantprefixlen = 0 - x = '%d' % self.ip + x = "%d" % self.ip return x + self._printPrefix(wantprefixlen) def iptype(self): @@ -581,10 +579,8 @@ class IPint(object): raise ValueError("Only adjacent networks can be added together.") ret = IP(self.int(), ipversion=self._ipversion) ret._prefixlen = self.prefixlen() - 1 - if not _checkNetaddrWorksWithPrefixlen(ret.ip, ret._prefixlen, - ret._ipversion): - raise ValueError("The resulting %s has invalid prefix length (%s)" - % (repr(ret), ret._prefixlen)) + if not _checkNetaddrWorksWithPrefixlen(ret.ip, ret._prefixlen, ret._ipversion): + raise ValueError("The resulting %s has invalid prefix length (%s)" % (repr(ret), ret._prefixlen)) return ret def __sub__(self, other): @@ -692,7 +688,7 @@ class IPint(object): IP('10.0.0.0/24') """ - return ("IPint('%s')" % (self.strCompressed(1))) + return "IPint('%s')" % (self.strCompressed(1)) def __cmp__(self, other): """Called by comparison operations. @@ -777,7 +773,7 @@ class IPint(object): thehash = int(-1) ip = self.ip while ip > 0: - thehash = thehash ^ (ip & 0x7fffffff) + thehash = thehash ^ (ip & 0x7FFFFFFF) ip = ip >> 32 thehash = thehash ^ self._prefixlen return int(thehash) @@ -811,17 +807,17 @@ class IP(IPint): >>> IP('10.0.0.0/8').netmask() IP('255.0.0.0') - """ + """ return IP(IPint.netmask(self), ipversion=self._ipversion) def _getIPv4Map(self): if self._ipversion != 6: return None - if (self.ip >> 32) != 0xffff: + if (self.ip >> 32) != 0xFFFF: return None ipv4 = self.ip & MAX_IPV4_ADDRESS if self._prefixlen != 128: - ipv4 = '%s/%s' % (ipv4, 32 - (128 - self._prefixlen)) + ipv4 = "%s/%s" % (ipv4, 32 - (128 - self._prefixlen)) return IP(ipv4, ipversion=4) def reverseNames(self): @@ -872,7 +868,7 @@ class IP(IPint): raise NotImplementedError("can't create IPv6 reverse names at sub nibble level") s = list(s) s.reverse() - s = '.'.join(s) + s = ".".join(s) first_nibble_index = int(32 - (self._prefixlen // 4)) * 2 return ["%s.ip6.arpa." % s[first_nibble_index:]] else: @@ -897,32 +893,34 @@ class IP(IPint): if self._ipversion == 4: s = self.strFullsize(0) - s = s.split('.') + s = s.split(".") s.reverse() first_byte_index = int(4 - (self._prefixlen // 8)) if self._prefixlen % 8 != 0: nibblepart = "%s-%s" % ( - s[3 - (self._prefixlen // 8)], intToIp(self.ip + self.len() - 1, 4).split('.')[-1]) - nibblepart += '.' + s[3 - (self._prefixlen // 8)], + intToIp(self.ip + self.len() - 1, 4).split(".")[-1], + ) + nibblepart += "." else: nibblepart = "" - s = '.'.join(s[first_byte_index:]) + s = ".".join(s[first_byte_index:]) return "%s%s.in-addr.arpa." % (nibblepart, s) elif self._ipversion == 6: ipv4 = self._getIPv4Map() if ipv4 is not None: return ipv4.reverseName() - s = '%032x' % self.ip + s = "%032x" % self.ip if self._prefixlen % 4 != 0: - nibblepart = "%s-%x" % (s[self._prefixlen:], self.ip + self.len() - 1) - nibblepart += '.' + nibblepart = "%s-%x" % (s[self._prefixlen :], self.ip + self.len() - 1) + nibblepart += "." else: nibblepart = "" s = list(s) s.reverse() - s = '.'.join(s) + s = ".".join(s) first_nibble_index = int(32 - (self._prefixlen // 4)) * 2 return "%s%s.ip6.arpa." % (nibblepart, s[first_nibble_index:]) else: @@ -937,9 +935,9 @@ class IP(IPint): >>> print(IP('127.0.0.1').make_net('255.0.0.0')) 127.0.0.0/8 """ - if '/' in str(netmask): + if "/" in str(netmask): raise ValueError("invalid netmask (%s)" % netmask) - return IP('%s/%s' % (self, netmask), make_net=True) + return IP("%s/%s" % (self, netmask), make_net=True) def __getitem__(self, key): """Called to implement evaluation of self[key]. @@ -968,7 +966,7 @@ class IP(IPint): IP('10.0.0.0/8') """ - return ("IP('%s')" % (self.strCompressed(1))) + return "IP('%s')" % (self.strCompressed(1)) def get_mac(self): """ @@ -980,15 +978,15 @@ class IP(IPint): """ if self._ipversion != 6: return None - if (self.ip & 0x20000ffff000000) != 0x20000fffe000000: + if (self.ip & 0x20000FFFF000000) != 0x20000FFFE000000: return None - return '%02x:%02x:%02x:%02x:%02x:%02x' % ( - (((self.ip >> 56) & 0xff) & 0xfd), - (self.ip >> 48) & 0xff, - (self.ip >> 40) & 0xff, - (self.ip >> 16) & 0xff, - (self.ip >> 8) & 0xff, - self.ip & 0xff, + return "%02x:%02x:%02x:%02x:%02x:%02x" % ( + (((self.ip >> 56) & 0xFF) & 0xFD), + (self.ip >> 48) & 0xFF, + (self.ip >> 40) & 0xFF, + (self.ip >> 16) & 0xFF, + (self.ip >> 8) & 0xFF, + self.ip & 0xFF, ) def v46map(self): @@ -1003,14 +1001,11 @@ class IP(IPint): IP('192.168.1.1') """ if self._ipversion == 4: - return IP(str(IPV6_MAP_MASK + self.ip) + - "/%s" % (self._prefixlen + 96)) + return IP(str(IPV6_MAP_MASK + self.ip) + "/%s" % (self._prefixlen + 96)) else: if self.ip & IPV6_TEST_MAP == IPV6_MAP_MASK: - return IP(str(self.ip - IPV6_MAP_MASK) + - "/%s" % (self._prefixlen - 96)) - raise ValueError("%s cannot be converted to an IPv4 address." - % repr(self)) + return IP(str(self.ip - IPV6_MAP_MASK) + "/%s" % (self._prefixlen - 96)) + raise ValueError("%s cannot be converted to an IPv4 address." % repr(self)) class IPSet(collections.MutableSet): @@ -1022,7 +1017,7 @@ class IPSet(collections.MutableSet): # Make sure we only accept IP objects for prefix in iterable: if not isinstance(prefix, IP): - raise ValueError('Only IP objects can be added to an IPSet') + raise ValueError("Only IP objects can be added to an IPSet") # Store and optimize self.prefixes = iterable[:] @@ -1083,7 +1078,7 @@ class IPSet(collections.MutableSet): return IPSet(result) def __repr__(self): - return '%s([' % self.__class__.__name__ + ', '.join(map(repr, self.prefixes)) + '])' + return "%s([" % self.__class__.__name__ + ", ".join(map(repr, self.prefixes)) + "])" def len(self): return sum(prefix.len() for prefix in self.prefixes) @@ -1096,7 +1091,7 @@ class IPSet(collections.MutableSet): # Check type for prefix in value: if not isinstance(prefix, IP): - raise ValueError('Only IP objects can be added to an IPSet') + raise ValueError("Only IP objects can be added to an IPSet") # Append and optimize self.prefixes.extend(value) @@ -1114,7 +1109,7 @@ class IPSet(collections.MutableSet): # Remove for del_prefix in value: if not isinstance(del_prefix, IP): - raise ValueError('Only IP objects can be removed from an IPSet') + raise ValueError("Only IP objects can be removed from an IPSet") # First check if this prefix contains anything in our list found = False @@ -1134,7 +1129,7 @@ class IPSet(collections.MutableSet): found = False for i in range(len(self.prefixes)): if del_prefix in self.prefixes[i]: - self.prefixes[i:i + 1] = self.prefixes[i] - del_prefix + self.prefixes[i : i + 1] = self.prefixes[i] - del_prefix break self.optimize() @@ -1279,13 +1274,13 @@ def _parseAddressIPv6(ipstr): fill_pos = len(items) index += 2 continue - pos = text.find(':') + pos = text.find(":") if pos == 0: # Invalid IPv6, eg. '1::2:' raise ValueError("%r: Invalid IPv6 address" % ipstr) if pos != -1: items.append(text[:pos]) - if text[pos:pos + 2] == "::": + if text[pos : pos + 2] == "::": index += pos else: index += pos + 1 @@ -1297,13 +1292,13 @@ def _parseAddressIPv6(ipstr): items.append(text) break - if items and '.' in items[-1]: + if items and "." in items[-1]: # IPv6 ending with IPv4 like '::ffff:192.168.0.1' if (fill_pos is not None) and not (fill_pos <= len(items) - 1): # Invalid IPv6: 'ffff:192.168.0.1::' raise ValueError("%r: Invalid IPv6 address: '::' after IPv4" % ipstr) value = parseAddress(items[-1])[0] - items = items[:-1] + ["%04x" % (value >> 16), "%04x" % (value & 0xffff)] + items = items[:-1] + ["%04x" % (value >> 16), "%04x" % (value & 0xFFFF)] # Expand fill_pos to fill with '0' # ['1','2'] with fill_pos=1 => ['1', '0', '0', '0', '0', '0', '0', '2'] @@ -1311,7 +1306,7 @@ def _parseAddressIPv6(ipstr): diff = 8 - len(items) if diff <= 0: raise ValueError("%r: Invalid IPv6 address: '::' is not needed" % ipstr) - items = items[:fill_pos] + ['0'] * diff + items[fill_pos:] + items = items[:fill_pos] + ["0"] * diff + items[fill_pos:] # Here we have a list of 8 strings if len(items) != 8: @@ -1324,7 +1319,7 @@ def _parseAddressIPv6(ipstr): for item in items: try: item = int(item, 16) - error = not (0 <= item <= 0xffff) + error = not (0 <= item <= 0xFFFF) except ValueError: error = True if error: @@ -1388,7 +1383,7 @@ def parseAddress(ipstr, ipversion=0): except ValueError: intval = None - if ipstr.startswith('0x') and hexval is not None: + if ipstr.startswith("0x") and hexval is not None: if hexval > MAX_IPV6_ADDRESS: raise ValueError("IP Address can't be larger than %x: %x" % (MAX_IPV6_ADDRESS, hexval)) if hexval <= MAX_IPV4_ADDRESS: @@ -1396,19 +1391,19 @@ def parseAddress(ipstr, ipversion=0): else: return (hexval, 6) - if ipstr.find(':') != -1: + if ipstr.find(":") != -1: return (_parseAddressIPv6(ipstr), 6) elif len(ipstr) == 32 and hexval is not None: # assume IPv6 in pure hexadecimal notation return (hexval, 6) - elif ipstr.find('.') != -1 or (intval is not None and intval < 256 and ipversion != 6): + elif ipstr.find(".") != -1 or (intval is not None and intval < 256 and ipversion != 6): # assume IPv4 ('127' gets interpreted as '127.0.0.0') - bytes = ipstr.split('.') + bytes = ipstr.split(".") if len(bytes) > 4: raise ValueError("IPv4 Address with more than 4 bytes") - bytes += ['0'] * (4 - len(bytes)) + bytes += ["0"] * (4 - len(bytes)) bytes = [int(x) for x in bytes] for x in bytes: if x > 255 or x < 0: @@ -1438,12 +1433,12 @@ def intToIp(ip, version): if ip < 0: raise ValueError("IPs can't be negative: %d" % (ip)) - ret = '' + ret = "" if version == 4: if ip > MAX_IPV4_ADDRESS: raise ValueError("IPv4 Address can't be larger than %x: %x" % (MAX_IPV4_ADDRESS, ip)) for l in xrange(4): - ret = str(ip & 0xff) + '.' + ret + ret = str(ip & 0xFF) + "." + ret ip = ip >> 8 ret = ret[:-1] elif version == 6: @@ -1453,7 +1448,7 @@ def intToIp(ip, version): for x in xrange(1, 33): ret = l[-x] + ret if x % 4 == 0: - ret = ':' + ret + ret = ":" + ret ret = ret[1:] else: raise ValueError("only IPv4 and IPv6 supported") @@ -1494,10 +1489,24 @@ def _countFollowingZeros(l): return 1 + _countFollowingZeros(l[1:]) -_BitTable = {'0': '0000', '1': '0001', '2': '0010', '3': '0011', - '4': '0100', '5': '0101', '6': '0110', '7': '0111', - '8': '1000', '9': '1001', 'a': '1010', 'b': '1011', - 'c': '1100', 'd': '1101', 'e': '1110', 'f': '1111'} +_BitTable = { + "0": "0000", + "1": "0001", + "2": "0010", + "3": "0011", + "4": "0100", + "5": "0101", + "6": "0110", + "7": "0111", + "8": "1000", + "9": "1001", + "a": "1010", + "b": "1011", + "c": "1100", + "d": "1101", + "e": "1110", + "f": "1111", +} def _intToBin(val): @@ -1506,11 +1515,11 @@ def _intToBin(val): if val < 0: raise ValueError("Only positive values allowed") s = "%x" % val - ret = '' + ret = "" for x in s: ret += _BitTable[x] # remove leading zeros - while ret[0] == '0' and len(ret) > 1: + while ret[0] == "0" and len(ret) > 1: ret = ret[1:] return ret @@ -1595,7 +1604,7 @@ def _checkNetmask(netmask, masklen): def _checkNetaddrWorksWithPrefixlen(net, prefixlen, version): """Check if a base addess of a network is compatible with a prefixlen""" try: - return (net & _prefixlenToNetmask(prefixlen, version) == net) + return net & _prefixlenToNetmask(prefixlen, version) == net except ValueError: return False @@ -1637,8 +1646,8 @@ def _remove_subprefix(prefix, subprefix): # Start cutting in half, recursively prefixes = [ - IP('%s/%d' % (prefix[0], prefix._prefixlen + 1)), - IP('%s/%d' % (prefix[int(prefix.len() / 2)], prefix._prefixlen + 1)), + IP("%s/%d" % (prefix[0], prefix._prefixlen + 1)), + IP("%s/%d" % (prefix[int(prefix.len() / 2)], prefix._prefixlen + 1)), ] if subprefix in prefixes[0]: return _remove_subprefix(prefixes[0], subprefix) + IPSet([prefixes[1]]) diff --git a/vrtManager/connection.py b/vrtManager/connection.py index 4ac9f4f..fc6e02e 100644 --- a/vrtManager/connection.py +++ b/vrtManager/connection.py @@ -1,11 +1,13 @@ -import libvirt -import threading -import socket import re -from vrtManager import util -from vrtManager.rwlock import ReadWriteLock +import socket +import threading +import libvirt + from django.conf import settings from libvirt import libvirtError +from vrtManager import util +from vrtManager.rwlock import ReadWriteLock + CONN_SOCKET = 4 CONN_TLS = 3 @@ -18,6 +20,7 @@ TCP_PORT = 16509 class wvmEventLoop(threading.Thread): """ Event Loop Class""" + def __init__(self, group=None, target=None, name=None, args=(), kwargs={}): # register the default event implementation # of libvirt, as we do not have an existing @@ -25,7 +28,7 @@ class wvmEventLoop(threading.Thread): libvirt.virEventRegisterDefaultImpl() if name is None: - name = 'libvirt event loop' + name = "libvirt event loop" super(wvmEventLoop, self).__init__(group, target, name, args, kwargs) @@ -46,6 +49,7 @@ class wvmConnection(object): class representing a single connection stored in the Connection Manager # to-do: may also need some locking to ensure to not connect simultaniously in 2 threads """ + def __init__(self, host, login, passwd, conn): """ Sets all class attributes and tries to open the connection @@ -86,7 +90,9 @@ class wvmConnection(object): # * set keep alive interval # * set connection close/fail handler try: - self.connection.setKeepAlive(connection_manager.keepalive_interval, connection_manager.keepalive_count) + self.connection.setKeepAlive( + connection_manager.keepalive_interval, connection_manager.keepalive_count + ) try: self.connection.registerCloseCallback(self.__connection_close_callback, None) except: @@ -134,49 +140,49 @@ class wvmConnection(object): def __connect_tcp(self): flags = [libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_PASSPHRASE] auth = [flags, self.__libvirt_auth_credentials_callback, None] - uri = f'qemu+tcp://{self.host}/system' + uri = f"qemu+tcp://{self.host}/system" try: self.connection = libvirt.openAuth(uri, auth, 0) self.last_error = None except libvirtError as e: - self.last_error = f'Connection Failed: {str(e)}' + self.last_error = f"Connection Failed: {str(e)}" self.connection = None def __connect_ssh(self): - uri = 'qemu+ssh://%s@%s/system' % (self.login, self.host) + uri = "qemu+ssh://%s@%s/system" % (self.login, self.host) try: self.connection = libvirt.open(uri) self.last_error = None except libvirtError as e: - self.last_error = f'Connection Failed: {str(e)} --- ' + repr(libvirt.virGetLastError()) + self.last_error = f"Connection Failed: {str(e)} --- " + repr(libvirt.virGetLastError()) self.connection = None def __connect_tls(self): flags = [libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_PASSPHRASE] auth = [flags, self.__libvirt_auth_credentials_callback, None] - uri = 'qemu+tls://%s@%s/system' % (self.login, self.host) + uri = "qemu+tls://%s@%s/system" % (self.login, self.host) try: self.connection = libvirt.openAuth(uri, auth, 0) self.last_error = None except libvirtError as e: - self.last_error = f'Connection Failed: {str(e)}' + self.last_error = f"Connection Failed: {str(e)}" self.connection = None def __connect_socket(self): - uri = 'qemu:///system' + uri = "qemu:///system" try: self.connection = libvirt.open(uri) self.last_error = None except libvirtError as e: - self.last_error = f'Connection Failed: {str(e)}' + self.last_error = f"Connection Failed: {str(e)}" self.connection = None def close(self): @@ -207,18 +213,18 @@ class wvmConnection(object): def __str__(self): if self.type == CONN_TCP: - type_str = 'tcp' + type_str = "tcp" elif self.type == CONN_SSH: - type_str = 'ssh' + type_str = "ssh" elif self.type == CONN_TLS: - type_str = 'tls' + type_str = "tls" else: - type_str = 'invalid_type' + type_str = "invalid_type" - return f'qemu+{type_str}://{self.login}@{self.host}/system' + return f"qemu+{type_str}://{self.login}@{self.host}/system" def __repr__(self): - return f'' + return f"" class wvmConnectionManager(object): @@ -307,7 +313,7 @@ class wvmConnectionManager(object): socket_host = socket.socket(socket.AF_INET, socket.SOCK_STREAM) socket_host.settimeout(1) if conn_type == CONN_SSH: - if ':' in hostname: + if ":" in hostname: libvirt_host, PORT = hostname.split(":") PORT = int(PORT) else: @@ -320,7 +326,7 @@ class wvmConnectionManager(object): 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.connect("/var/run/libvirt/libvirt-sock") socket_host.close() return True except Exception as err: @@ -328,8 +334,8 @@ class wvmConnectionManager(object): connection_manager = wvmConnectionManager( - settings.LIBVIRT_KEEPALIVE_INTERVAL if hasattr(settings, 'LIBVIRT_KEEPALIVE_INTERVAL') else 5, - settings.LIBVIRT_KEEPALIVE_COUNT if hasattr(settings, 'LIBVIRT_KEEPALIVE_COUNT') else 5, + settings.LIBVIRT_KEEPALIVE_INTERVAL if hasattr(settings, "LIBVIRT_KEEPALIVE_INTERVAL") else 5, + settings.LIBVIRT_KEEPALIVE_COUNT if hasattr(settings, "LIBVIRT_KEEPALIVE_COUNT") else 5, ) @@ -353,15 +359,16 @@ class wvmConnect(object): def get_dom_cap_xml(self, arch, machine): """ Return domain capabilities xml""" emulatorbin = self.get_emulator(arch) - virttype = 'kvm' if 'kvm' in self.get_hypervisors_domain_types()[arch] else 'qemu' + virttype = "kvm" if "kvm" in self.get_hypervisors_domain_types()[arch] else "qemu" machine_types = self.get_machine_types(arch) if not machine or machine not in machine_types: - machine = 'pc' if 'pc' in machine_types else machine_types[0] + machine = "pc" if "pc" in machine_types else machine_types[0] return self.wvm.getDomainCapabilities(emulatorbin, arch, machine, virttype) def get_capabilities(self, arch): """ Host Capabilities for specified architecture """ + def guests(ctx): result = dict() for arch_el in ctx.xpath("/capabilities/guest/arch[@name='{}']".format(arch)): @@ -371,11 +378,9 @@ class wvmConnect(object): result["machines"] = [] for m in arch_el.xpath("machine"): - result["machines"].append({ - "machine": m.text, - "max_cpu": m.get("maxCpus"), - "canonical": m.get("canonical") - }) + result["machines"].append( + {"machine": m.text, "max_cpu": m.get("maxCpus"), "canonical": m.get("canonical")} + ) guest_el = arch_el.getparent() for f in guest_el.xpath("features"): @@ -400,7 +405,7 @@ class wvmConnect(object): result["os_support"] = util.get_xml_path(xml, "/domainCapabilities/os/@supported") result["loader_support"] = util.get_xml_path(xml, "/domainCapabilities/os/loader/@supported") - if result["loader_support"] == 'yes': + if result["loader_support"] == "yes": result["loaders"] = self.get_os_loaders(arch, machine) result["loader_enums"] = self.get_os_loader_enums(arch, machine) @@ -410,27 +415,29 @@ class wvmConnect(object): result["cpu_custom_models"] = self.get_cpu_custom_types(arch, machine) result["disk_support"] = util.get_xml_path(xml, "/domainCapabilities/devices/disk/@supported") - if result["disk_support"] == 'yes': + if result["disk_support"] == "yes": result["disk_devices"] = self.get_disk_device_types(arch, machine) result["disk_bus"] = self.get_disk_bus_types(arch, machine) result["graphics_support"] = util.get_xml_path(xml, "/domainCapabilities/devices/graphics/@supported") - if result["graphics_support"] == 'yes': + if result["graphics_support"] == "yes": result["graphics_types"] = self.get_graphics_types(arch, machine) result["video_support"] = util.get_xml_path(xml, "/domainCapabilities/devices/video/@supported") - if result["video_support"] == 'yes': + if result["video_support"] == "yes": result["video_types"] = self.get_video_models(arch, machine) result["hostdev_support"] = util.get_xml_path(xml, "/domainCapabilities/devices/hostdev/@supported") - if result["hostdev_support"] == 'yes': + if result["hostdev_support"] == "yes": result["hostdev_types"] = self.get_hostdev_modes(arch, machine) result["hostdev_startup_policies"] = self.get_hostdev_startup_policies(arch, machine) result["hostdev_subsys_types"] = self.get_hostdev_subsys_types(arch, machine) result["features_gic_support"] = util.get_xml_path(xml, "/domainCapabilities/features/gic/@supported") result["features_genid_support"] = util.get_xml_path(xml, "/domainCapabilities/features/genid/@supported") - result["features_vmcoreinfo_support"] = util.get_xml_path(xml, "/domainCapabilities/features/vmcoreinfo/@supported") + result["features_vmcoreinfo_support"] = util.get_xml_path( + xml, "/domainCapabilities/features/vmcoreinfo/@supported" + ) result["features_sev_support"] = util.get_xml_path(xml, "/domainCapabilities/features/sev/@supported") return result @@ -510,12 +517,12 @@ class wvmConnect(object): :return: Get cache available modes """ return { - 'default': 'Default', - 'none': 'Disabled', - 'writethrough': 'Write through', - 'writeback': 'Write back', - 'directsync': 'Direct sync', # since libvirt 0.9.5 - 'unsafe': 'Unsafe', # since libvirt 0.9.7 + "default": "Default", + "none": "Disabled", + "writethrough": "Write through", + "writeback": "Write back", + "directsync": "Direct sync", # since libvirt 0.9.5 + "unsafe": "Unsafe", # since libvirt 0.9.7 } def get_io_modes(self): @@ -523,9 +530,9 @@ class wvmConnect(object): :return: available io modes """ return { - 'default': 'Default', - 'native': 'Native', - 'threads': 'Threads', + "default": "Default", + "native": "Native", + "threads": "Threads", } def get_discard_modes(self): @@ -533,9 +540,9 @@ class wvmConnect(object): :return: available discard modes """ return { - 'default': 'Default', - 'ignore': 'Ignore', - 'unmap': 'Unmap', + "default": "Default", + "ignore": "Ignore", + "unmap": "Unmap", } def get_detect_zeroes_modes(self): @@ -543,21 +550,22 @@ class wvmConnect(object): :return: available detect zeroes modes """ return { - 'default': 'Default', - 'on': 'On', - 'off': 'Off', - 'unmap': 'Unmap', + "default": "Default", + "on": "On", + "off": "Off", + "unmap": "Unmap", } def get_hypervisors_domain_types(self): """ :return: hypervisor domain types """ + def hypervisors(ctx): result = {} - for arch in ctx.xpath('/capabilities/guest/arch'): - domain_types = arch.xpath('domain/@type') - arch_name = arch.xpath('@name')[0] + for arch in ctx.xpath("/capabilities/guest/arch"): + domain_types = arch.xpath("domain/@type") + arch_name = arch.xpath("@name")[0] result[arch_name] = domain_types return result @@ -567,9 +575,10 @@ class wvmConnect(object): """ :return: hypervisor and its machine types """ + def machines(ctx): result = dict() - for arche in ctx.xpath('/capabilities/guest/arch'): + for arche in ctx.xpath("/capabilities/guest/arch"): arch = arche.get("name") result[arch] = self.get_machine_types(arch) @@ -587,6 +596,7 @@ class wvmConnect(object): """ :return: canonical(if exist) name of machine types """ + def machines(ctx): result = list() canonical_name = ctx.xpath("/capabilities/guest/arch[@name='{}']/machine[@canonical]".format(arch)) @@ -602,22 +612,24 @@ class wvmConnect(object): """ :return: host emulators list """ + def emulators(ctx): result = {} - for arch in ctx.xpath('/capabilities/guest/arch'): - emulator = arch.xpath('emulator') - arch_name = arch.xpath('@name')[0] + for arch in ctx.xpath("/capabilities/guest/arch"): + emulator = arch.xpath("emulator") + arch_name = arch.xpath("@name")[0] result[arch_name] = emulator return result 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"): """ :param arch: architecture :param machine: :return: available os loaders list """ + def get_os_loaders(ctx): return [v.text for v in ctx.xpath("/domainCapabilities/os/loader[@supported='yes']/value")] @@ -629,6 +641,7 @@ class wvmConnect(object): :param machine: :return: available os loaders list """ + def get_os_loader_enums(ctx): result = dict() enums = [v for v in ctx.xpath("/domainCapabilities/os/loader[@supported='yes']/enum/@name")] @@ -645,6 +658,7 @@ class wvmConnect(object): :param arch: :return: available disk bus types list """ + def get_bus_list(ctx): return [v.text for v in ctx.xpath("/domainCapabilities/devices/disk/enum[@name='bus']/value")] @@ -657,6 +671,7 @@ class wvmConnect(object): :param machine: :return: available disk device type list """ + def get_device_list(ctx): return [v.text for v in ctx.xpath("/domainCapabilities/devices/disk/enum[@name='diskDevice']/value")] @@ -669,6 +684,7 @@ class wvmConnect(object): :param machine: :return: available graphics types """ + def get_graphics_list(ctx): return [v.text for v in ctx.xpath("/domainCapabilities/devices/graphics/enum[@name='type']/value")] @@ -680,6 +696,7 @@ class wvmConnect(object): :param machine: :return: available cpu modes """ + def get_cpu_modes(ctx): return [v for v in ctx.xpath("/domainCapabilities/cpu/mode[@supported='yes']/@name")] @@ -691,6 +708,7 @@ class wvmConnect(object): :param machine: :return: available graphics types """ + def get_custom_list(ctx): usable_yes = "/domainCapabilities/cpu/mode[@name='custom'][@supported='yes']/model[@usable='yes']" usable_unknown = "/domainCapabilities/cpu/mode[@name='custom'][@supported='yes']/model[@usable='unknown']" @@ -706,6 +724,7 @@ class wvmConnect(object): :param machine: :return. available nodedev modes """ + def get_hostdev_list(ctx): return [v.text for v in ctx.xpath("/domainCapabilities/devices/hostdev/enum[@name='mode']/value")] @@ -717,6 +736,7 @@ class wvmConnect(object): :param machine: :return: available hostdev modes """ + def get_hostdev_list(ctx): return [v.text for v in ctx.xpath("/domainCapabilities/devices/hostdev/enum[@name='startupPolicy']/value")] @@ -728,6 +748,7 @@ class wvmConnect(object): :param machine: :return: available nodedev sub system types """ + def get_hostdev_list(ctx): return [v.text for v in ctx.xpath("/domainCapabilities/devices/hostdev/enum[@name='subsysType']/value")] @@ -737,19 +758,19 @@ class wvmConnect(object): """ :return: network card models """ - return ['default', 'e1000', 'virtio'] + return ["default", "e1000", "virtio"] def get_image_formats(self): """ :return: available image formats """ - return ['raw', 'qcow', 'qcow2'] + return ["raw", "qcow", "qcow2"] def get_file_extensions(self): """ :return: available image filename extensions """ - return ['img', 'qcow', 'qcow2'] + return ["img", "qcow", "qcow2"] def get_video_models(self, arch, machine): """ @@ -757,9 +778,10 @@ class wvmConnect(object): :param machine: :return: available graphics video types """ + def get_video_list(ctx): 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": for values in video_enum: result.append(values.text) @@ -787,8 +809,8 @@ class wvmConnect(object): def get_network_forward(self, net_name): def get_forward(doc): - forward_mode = util.get_xpath(doc, '/network/forward/@mode') - return forward_mode or 'isolated' + forward_mode = util.get_xpath(doc, "/network/forward/@mode") + return forward_mode or "isolated" net = self.get_network(net_name) xml = net.XMLDesc(0) @@ -825,14 +847,14 @@ class wvmConnect(object): netdevice = [] def get_info(doc): - dev_type = util.get_xpath(doc, '/device/capability/@type') - interface = util.get_xpath(doc, '/device/capability/interface') + dev_type = util.get_xpath(doc, "/device/capability/@type") + interface = util.get_xpath(doc, "/device/capability/interface") return dev_type, interface for dev in self.wvm.listAllDevices(0): xml = dev.XMLDesc(0) (dev_type, interface) = util.get_xml_path(xml, func=get_info) - if dev_type == 'net': + if dev_type == "net": netdevice.append(interface) return netdevice @@ -850,9 +872,9 @@ class wvmConnect(object): else: vcpu = util.get_xpath(doc, "/domain/vcpu") title = util.get_xpath(doc, "/domain/title") - title = title if title else '' + title = title if title else "" description = util.get_xpath(doc, "/domain/description") - description = description if description else '' + description = description if description else "" return mem, vcpu, title, description for name in self.get_instances(): @@ -860,12 +882,12 @@ class wvmConnect(object): xml = dom.XMLDesc(0) (mem, vcpu, title, description) = util.get_xml_path(xml, func=get_info) vname[dom.name()] = { - 'status': dom.info()[0], - 'uuid': dom.UUIDString(), - 'vcpu': vcpu, - 'memory': mem, - 'title': title, - 'description': description, + "status": dom.info()[0], + "uuid": dom.UUIDString(), + "vcpu": vcpu, + "memory": mem, + "title": title, + "description": description, } return vname @@ -882,20 +904,20 @@ class wvmConnect(object): else: vcpu = util.get_xpath(ctx, "/domain/vcpu") title = util.get_xpath(ctx, "/domain/title") - title = title if title else '' + title = title if title else "" description = util.get_xpath(ctx, "/domain/description") - description = description if description else '' + description = description if description else "" return mem, vcpu, title, description (mem, vcpu, title, description) = util.get_xml_path(xml, func=get_info) return { - 'name': dom.name(), - 'status': dom.info()[0], - 'uuid': dom.UUIDString(), - 'vcpu': vcpu, - 'memory': mem, - 'title': title, - 'description': description, + "name": dom.name(), + "status": dom.info()[0], + "uuid": dom.UUIDString(), + "vcpu": vcpu, + "memory": mem, + "title": title, + "description": description, } def close(self): @@ -931,7 +953,7 @@ class wvmConnect(object): for arch, patterns in util.UEFI_ARCH_PATTERNS.items(): for pattern in patterns: if re.match(pattern, path): - return ("UEFI %(arch)s: %(path)s" % {"arch": arch, "path": path}) + return "UEFI %(arch)s: %(path)s" % {"arch": arch, "path": path} return "Custom: %(path)s" % {"path": path} @@ -945,15 +967,17 @@ class wvmConnect(object): """ Return True if libvirt advertises support for proper UEFI setup """ - return ("readonly" in loader_enums and "yes" in loader_enums.get("readonly")) + return "readonly" in loader_enums and "yes" in loader_enums.get("readonly") def is_supports_virtio(self, arch, machine): if not self.is_qemu(): return False # These _only_ support virtio so don't check the OS - if arch in ["aarch64", "armv7l", "ppc64", "ppc64le", "s390x", "riscv64", "riscv32"] and \ - machine in ["virt", "pseries"]: + if arch in ["aarch64", "armv7l", "ppc64", "ppc64le", "s390x", "riscv64", "riscv32"] and machine in [ + "virt", + "pseries", + ]: return True if arch in ["x86_64", "i686"]: diff --git a/vrtManager/create.py b/vrtManager/create.py index 641715c..5d9bc64 100644 --- a/vrtManager/create.py +++ b/vrtManager/create.py @@ -1,4 +1,5 @@ import string + from vrtManager import util from vrtManager.connection import wvmConnect @@ -12,15 +13,15 @@ def get_rbd_storage_data(stg): for host in doc.xpath("/pool/source/host"): name = host.prop("name") if name: - hosts.append({'name': name, 'port': host.prop("port")}) + hosts.append({"name": name, "port": host.prop("port")}) return hosts + ceph_hosts = util.get_xml_path(xml, func=get_ceph_hosts) secret_uuid = util.get_xml_path(xml, "/pool/source/auth/secret/@uuid") return ceph_user, secret_uuid, ceph_hosts class wvmCreate(wvmConnect): - def get_storages_images(self): """ Function return all images on all storages @@ -34,7 +35,7 @@ class wvmCreate(wvmConnect): except: pass for img in stg.listVolumes(): - if img.lower().endswith('.iso'): + if img.lower().endswith(".iso"): pass else: images.append(img) @@ -52,11 +53,11 @@ class wvmCreate(wvmConnect): size = int(size) * 1073741824 stg = self.get_storage(storage) storage_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type") - if storage_type == 'dir': - if image_format in ('qcow', 'qcow2'): - name += '.' + image_format + if storage_type == "dir": + if image_format in ("qcow", "qcow2"): + name += "." + image_format else: - name += '.img' + name += ".img" alloc = 0 else: alloc = size @@ -91,12 +92,12 @@ class wvmCreate(wvmConnect): def get_volume_type(self, path): vol = self.get_volume_by_path(path) vol_type = util.get_xml_path(vol.XMLDesc(0), "/volume/target/format/@type") - if vol_type == 'unknown' or vol_type == 'iso': - return 'raw' + if vol_type == "unknown" or vol_type == "iso": + return "raw" if vol_type: return vol_type else: - return 'raw' + return "raw" def get_volume_path(self, volume, pool=None): if not pool: @@ -125,8 +126,8 @@ class wvmCreate(wvmConnect): storage_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type") format = util.get_xml_path(vol.XMLDesc(0), "/volume/target/format/@type") - if storage_type == 'dir': - clone += '.img' + if storage_type == "dir": + clone += ".img" else: metadata = False xml = f""" @@ -159,9 +160,27 @@ class wvmCreate(wvmConnect): vol = self.get_volume_by_path(path) vol.delete() - def create_instance(self, name, memory, vcpu, vcpu_mode, uuid, arch, machine, firmware, volumes, - networks, nwfilter, graphics, virtio, listen_addr, - video="vga", console_pass="random", mac=None, qemu_ga=True): + def create_instance( + self, + name, + memory, + vcpu, + vcpu_mode, + uuid, + arch, + machine, + firmware, + volumes, + networks, + nwfilter, + graphics, + virtio, + listen_addr, + video="vga", + console_pass="random", + mac=None, + qemu_ga=True, + ): """ Create VM function """ @@ -178,33 +197,37 @@ class wvmCreate(wvmConnect): {memory} {vcpu}""" - if dom_caps["os_support"] == 'yes': + if dom_caps["os_support"] == "yes": xml += f""" {caps["os_type"]}""" xml += """ """ if firmware: - if firmware["secure"] == 'yes': - xml += """%s""" % (firmware["readonly"], - firmware["type"], - firmware["secure"], - firmware["loader"]) - if firmware["secure"] == 'no': - xml += """%s""" % (firmware["readonly"], - firmware["type"], - firmware["loader"]) + if firmware["secure"] == "yes": + xml += """%s""" % ( + firmware["readonly"], + firmware["type"], + firmware["secure"], + firmware["loader"], + ) + if firmware["secure"] == "no": + xml += """%s""" % ( + firmware["readonly"], + firmware["type"], + firmware["loader"], + ) xml += """""" if caps["features"]: xml += """""" - if 'acpi' in caps["features"]: + if "acpi" in caps["features"]: xml += """""" - if 'apic' in caps["features"]: + if "apic" in caps["features"]: xml += """""" - if 'pae' in caps["features"]: + if "pae" in caps["features"]: xml += """""" - if firmware.get("secure", 'no') == 'yes': + if firmware.get("secure", "no") == "yes": xml += """""" xml += """""" @@ -235,56 +258,69 @@ class wvmCreate(wvmConnect): for volume in volumes: - disk_opts = '' - if volume['cache_mode'] is not None and volume['cache_mode'] != 'default': + disk_opts = "" + if volume["cache_mode"] is not None and volume["cache_mode"] != "default": disk_opts += f"cache='{volume['cache_mode']}' " - if volume['io_mode'] is not None and volume['io_mode'] != 'default': + if volume["io_mode"] is not None and volume["io_mode"] != "default": disk_opts += f"io='{volume['io_mode']}' " - if volume['discard_mode'] is not None and volume['discard_mode'] != 'default': + if volume["discard_mode"] is not None and volume["discard_mode"] != "default": disk_opts += f"discard='{volume['discard_mode']}' " - if volume['detect_zeroes_mode'] is not None and volume['detect_zeroes_mode'] != 'default': + if volume["detect_zeroes_mode"] is not None and volume["detect_zeroes_mode"] != "default": disk_opts += f"detect_zeroes='{volume['detect_zeroes_mode']}' " - stg = self.get_storage_by_vol_path(volume['path']) + stg = self.get_storage_by_vol_path(volume["path"]) stg_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type") - if volume['device'] == 'cdrom': add_cd = False + if volume["device"] == "cdrom": + add_cd = False - if stg_type == 'rbd': + if stg_type == "rbd": ceph_user, secret_uuid, ceph_hosts = get_rbd_storage_data(stg) xml += """ - """ % (volume['type'], disk_opts) + """ % ( + volume["type"], + disk_opts, + ) xml += """ - """ % (ceph_user, secret_uuid, volume['path']) + """ % ( + ceph_user, + secret_uuid, + volume["path"], + ) if isinstance(ceph_hosts, list): for host in ceph_hosts: - if host.get('port'): + if host.get("port"): xml += """ - """ % (host.get('name'), host.get('port')) + """ % ( + host.get("name"), + host.get("port"), + ) else: xml += """ - """ % host.get('name') + """ % host.get( + "name" + ) xml += """""" else: - xml += """""" % volume['device'] - xml += """ """ % (volume['type'], disk_opts) - xml += f""" """ % volume['path'] + xml += """""" % volume["device"] + xml += """ """ % (volume["type"], disk_opts) + xml += """ """ % volume["path"] - if volume.get('bus') == 'virtio': - xml += """""" % (vd_disk_letters.pop(0), volume.get('bus')) - elif volume.get('bus') == 'ide': - xml += """""" % (hd_disk_letters.pop(0), volume.get('bus')) - elif volume.get('bus') == 'fdc': - xml += """""" % (fd_disk_letters.pop(0), volume.get('bus')) - elif volume.get('bus') == 'sata' or volume.get('bus') == 'scsi': - xml += """""" % (sd_disk_letters.pop(0), volume.get('bus')) + if volume.get("bus") == "virtio": + xml += """""" % (vd_disk_letters.pop(0), volume.get("bus")) + elif volume.get("bus") == "ide": + xml += """""" % (hd_disk_letters.pop(0), volume.get("bus")) + elif volume.get("bus") == "fdc": + xml += """""" % (fd_disk_letters.pop(0), volume.get("bus")) + elif volume.get("bus") == "sata" or volume.get("bus") == "scsi": + xml += """""" % (sd_disk_letters.pop(0), volume.get("bus")) else: xml += """""" % sd_disk_letters.pop(0) xml += """""" - if volume.get('bus') == 'scsi': + if volume.get("bus") == "scsi": xml += f"""""" if add_cd: @@ -292,17 +328,17 @@ class wvmCreate(wvmConnect): """ - if 'ide' in dom_caps['disk_bus']: - xml += """""" % (hd_disk_letters.pop(0), 'ide') - elif 'sata' in dom_caps['disk_bus']: - xml += """""" % (sd_disk_letters.pop(0), 'sata') - elif 'scsi' in dom_caps['disk_bus']: - xml += """""" % (sd_disk_letters.pop(0), 'scsi') + if "ide" in dom_caps["disk_bus"]: + xml += """""" % (hd_disk_letters.pop(0), "ide") + elif "sata" in dom_caps["disk_bus"]: + xml += """""" % (sd_disk_letters.pop(0), "sata") + elif "scsi" in dom_caps["disk_bus"]: + xml += """""" % (sd_disk_letters.pop(0), "scsi") else: - xml += """""" % (vd_disk_letters.pop(0), 'virtio') + xml += """""" % (vd_disk_letters.pop(0), "virtio") xml += """""" - for net in networks.split(','): + for net in networks.split(","): xml += """""" if mac: xml += f"""""" @@ -319,10 +355,10 @@ class wvmCreate(wvmConnect): if not console_pass == "": console_pass = "passwd='" + console_pass + "'" - if 'usb' in dom_caps['disk_bus']: - xml += """""".format('virtio' if virtio else 'usb') - xml += """""".format('virtio' if virtio else 'usb') - xml += """""".format('virtio' if virtio else 'usb') + if "usb" in dom_caps["disk_bus"]: + xml += """""".format("virtio" if virtio else "usb") + xml += """""".format("virtio" if virtio else "usb") + xml += """""".format("virtio" if virtio else "usb") else: xml += """""" xml += """""" diff --git a/vrtManager/hostdetails.py b/vrtManager/hostdetails.py index f2defa3..2996904 100644 --- a/vrtManager/hostdetails.py +++ b/vrtManager/hostdetails.py @@ -1,14 +1,15 @@ import time + from vrtManager.connection import wvmConnect from vrtManager.util import get_xml_path def cpu_version(doc): - for info in doc.xpath('/sysinfo/processor/entry'): - elem = info.xpath('@name')[0] - if elem == 'version': + for info in doc.xpath("/sysinfo/processor/entry"): + elem = info.xpath("@name")[0] + if elem == "version": return info.text - return 'Unknown' + return "Unknown" class wvmHostDetails(wvmConnect): @@ -19,14 +20,12 @@ class wvmHostDetails(wvmConnect): all_mem = self.wvm.getInfo()[1] * 1048576 freemem = self.wvm.getMemoryStats(-1, 0) if isinstance(freemem, dict): - free = (freemem['buffers'] + - freemem['free'] + - freemem['cached']) * 1024 + free = (freemem["buffers"] + freemem["free"] + freemem["cached"]) * 1024 percent = abs(100 - ((free * 100) // all_mem)) - usage = (all_mem - free) - mem_usage = {'total': all_mem, 'usage': usage, 'percent': percent} + usage = all_mem - free + mem_usage = {"total": all_mem, "usage": usage, "percent": percent} else: - mem_usage = {'total': None, 'usage': None, 'percent': None} + mem_usage = {"total": None, "usage": None, "percent": None} return mem_usage def get_cpu_usage(self): @@ -38,7 +37,7 @@ class wvmHostDetails(wvmConnect): cpu = self.wvm.getCPUStats(-1, 0) if isinstance(cpu, dict): 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()) diff_idle = idle - prev_idle diff_total = total - prev_total @@ -51,8 +50,8 @@ class wvmHostDetails(wvmConnect): if diff_usage < 0: diff_usage = 0 else: - return {'usage': None} - return {'usage': diff_usage} + return {"usage": None} + return {"usage": diff_usage} def get_node_info(self): """ diff --git a/vrtManager/instance.py b/vrtManager/instance.py index a456ec6..4bb4a33 100644 --- a/vrtManager/instance.py +++ b/vrtManager/instance.py @@ -1,5 +1,6 @@ -import time import os.path +import time + try: from libvirt import ( libvirtError, @@ -7,9 +8,6 @@ try: VIR_DOMAIN_RUNNING, VIR_DOMAIN_AFFECT_LIVE, VIR_DOMAIN_AFFECT_CONFIG, - VIR_DOMAIN_UNDEFINE_NVRAM, - VIR_DOMAIN_UNDEFINE_KEEP_NVRAM, - VIR_DOMAIN_START_PAUSED ) from libvirt import ( VIR_MIGRATE_LIVE, @@ -19,16 +17,17 @@ try: VIR_MIGRATE_OFFLINE, VIR_MIGRATE_COMPRESSED, VIR_MIGRATE_AUTO_CONVERGE, - VIR_MIGRATE_POSTCOPY + VIR_MIGRATE_POSTCOPY, ) from libvirt import VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT except: from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE, VIR_MIGRATE_LIVE +from collections import OrderedDict +from datetime import datetime from xml.etree import ElementTree from lxml import etree -from datetime import datetime -from collections import OrderedDict + from vrtManager import util from vrtManager.connection import wvmConnect from vrtManager.storage import wvmStorage, wvmStorages @@ -112,7 +111,7 @@ class wvmInstances(wvmConnect): dom_emulator = conn.get_dom_emulator() if dom_emulator != self.get_emulator(dom_arch): - raise libvirtError('Destination host emulator is different. Cannot be migrated') + raise libvirtError("Destination host emulator is different. Cannot be migrated") dom.migrate(self.wvm, flags, None, None, 0) @@ -192,10 +191,10 @@ class wvmInstance(wvmConnect): def get_status(self): """ - VIR_DOMAIN_NOSTATE = 0 - VIR_DOMAIN_RUNNING = 1 - VIR_DOMAIN_PAUSED = 3 - VIR_DOMAIN_SHUTOFF = 5 + VIR_DOMAIN_NOSTATE = 0 + VIR_DOMAIN_RUNNING = 1 + VIR_DOMAIN_PAUSED = 3 + VIR_DOMAIN_SHUTOFF = 5 """ return self.instance.info()[0] @@ -260,13 +259,13 @@ class wvmInstance(wvmConnect): def get_title(self): title = util.get_xml_path(self._XMLDesc(0), "/domain/title") - return title if title else '' + return title if title else "" def get_filterrefs(self): def filterrefs(ctx): result = [] - for net in ctx.xpath('/domain/devices/interface'): - filterref = net.xpath('filterref/@filter') + for net in ctx.xpath("/domain/devices/interface"): + filterref = net.xpath("filterref/@filter") if filterref: result.append(filterref[0]) return result @@ -275,7 +274,7 @@ class wvmInstance(wvmConnect): def get_description(self): description = util.get_xml_path(self._XMLDesc(0), "/domain/description") - return description if description else '' + return description if description else "" def get_max_memory(self): return self.wvm.getInfo()[1] * 1048576 @@ -306,7 +305,7 @@ class wvmInstance(wvmConnect): for addr in addrs["addrs"]: if addr["type"] == 0: ipv4.append(addr["addr"]) - elif (addr["type"] == 1 and not str(addr["addr"]).startswith("fe80")): + elif addr["type"] == 1 and not str(addr["addr"]).startswith("fe80"): ipv6.append(addr["addr"] + "/" + str(addr["prefix"])) return ipv4, ipv6 @@ -320,7 +319,7 @@ class wvmInstance(wvmConnect): ipv6.append(info["ipaddr"]) return ipv4, ipv6 - for ips in ([qemuga] + leases + [arp]): + for ips in [qemuga] + leases + [arp]: if "expirytime" in ips: ipv4, ipv6 = extract_lease(ips) else: @@ -333,7 +332,7 @@ class wvmInstance(wvmConnect): # ("Calling interfaceAddresses source=%s", source) try: return self.instance.interfaceAddresses(source) - except libvirtError as e: + except libvirtError: # log.debug("interfaceAddresses failed: %s", str(e)) pass return {} @@ -354,44 +353,46 @@ class wvmInstance(wvmConnect): def networks(ctx): result = [] inbound = outbound = [] - for net in ctx.xpath('/domain/devices/interface'): - interface_type = net.xpath('@type')[0] - mac_inst = net.xpath('mac/@address')[0] - nic_inst = net.xpath('source/@network|source/@bridge|source/@dev')[0] - target_inst = '' if not net.xpath('target/@dev') else net.xpath('target/@dev')[0] - link_state = 'up' if not net.xpath('link') else net.xpath('link/@state')[0] - filterref_inst = '' if not net.xpath('filterref/@filter') else net.xpath('filterref/@filter')[0] - model_type = net.xpath('model/@type')[0] - if net.xpath('bandwidth/inbound'): - in_attr = net.xpath('bandwidth/inbound')[0] - in_av = in_attr.get('average') - in_peak = in_attr.get('peak') - in_burst = in_attr.get('burst') - inbound = {'average': in_av, 'peak': in_peak, 'burst': in_burst} - if net.xpath('bandwidth/outbound'): - out_attr = net.xpath('bandwidth/outbound')[0] - out_av = out_attr.get('average') - out_peak = out_attr.get('peak') - out_burst = out_attr.get('burst') - outbound = {'average': out_av, 'peak': out_peak, 'burst': out_burst} + for net in ctx.xpath("/domain/devices/interface"): + interface_type = net.xpath("@type")[0] + mac_inst = net.xpath("mac/@address")[0] + nic_inst = net.xpath("source/@network|source/@bridge|source/@dev")[0] + target_inst = "" if not net.xpath("target/@dev") else net.xpath("target/@dev")[0] + link_state = "up" if not net.xpath("link") else net.xpath("link/@state")[0] + filterref_inst = "" if not net.xpath("filterref/@filter") else net.xpath("filterref/@filter")[0] + model_type = net.xpath("model/@type")[0] + if net.xpath("bandwidth/inbound"): + in_attr = net.xpath("bandwidth/inbound")[0] + in_av = in_attr.get("average") + in_peak = in_attr.get("peak") + in_burst = in_attr.get("burst") + inbound = {"average": in_av, "peak": in_peak, "burst": in_burst} + if net.xpath("bandwidth/outbound"): + out_attr = net.xpath("bandwidth/outbound")[0] + out_av = out_attr.get("average") + out_peak = out_attr.get("peak") + out_burst = out_attr.get("burst") + outbound = {"average": out_av, "peak": out_peak, "burst": out_burst} try: ipv4, ipv6 = self.get_interface_addresses(mac_inst) except libvirtError: ipv4, ipv6 = None, None - result.append({ - 'type': interface_type, - 'mac': mac_inst, - 'nic': nic_inst, - 'target': target_inst, - 'state': link_state, - 'model': model_type, - 'ipv4': ipv4, - 'ipv6': ipv6, - 'filterref': filterref_inst, - 'inbound': inbound, - 'outbound': outbound, - }) + result.append( + { + "type": interface_type, + "mac": mac_inst, + "nic": nic_inst, + "target": target_inst, + "state": link_state, + "model": model_type, + "ipv4": ipv4, + "ipv6": ipv6, + "filterref": filterref_inst, + "inbound": inbound, + "outbound": outbound, + } + ) return result return util.get_xml_path(self._XMLDesc(0), func=networks) @@ -400,48 +401,48 @@ class wvmInstance(wvmConnect): def disks(doc): result = [] - for disk in doc.xpath('/domain/devices/disk'): + for disk in doc.xpath("/domain/devices/disk"): dev = volume = storage = src_file = bus = None disk_format = used_size = disk_size = None - disk_cache = disk_io = disk_discard = disk_zeroes = 'default' + disk_cache = disk_io = disk_discard = disk_zeroes = "default" readonly = shareable = serial = None - device = disk.xpath('@device')[0] - if device == 'disk': + device = disk.xpath("@device")[0] + if device == "disk": try: - dev = disk.xpath('target/@dev')[0] - bus = disk.xpath('target/@bus')[0] + dev = disk.xpath("target/@dev")[0] + bus = disk.xpath("target/@bus")[0] try: - src_file = disk.xpath('source/@file|source/@dev|source/@name')[0] - except Exception as e: - v = disk.xpath('source/@volume')[0] - s_name = disk.xpath('source/@pool')[0] + src_file = disk.xpath("source/@file|source/@dev|source/@name")[0] + except Exception: + v = disk.xpath("source/@volume")[0] + s_name = disk.xpath("source/@pool")[0] s = self.wvm.storagePoolLookupByName(s_name) src_file = s.storageVolLookupByName(v).path() try: - disk_format = disk.xpath('driver/@type')[0] + disk_format = disk.xpath("driver/@type")[0] except: pass try: - disk_cache = disk.xpath('driver/@cache')[0] + disk_cache = disk.xpath("driver/@cache")[0] except: pass try: - disk_io = disk.xpath('driver/@io')[0] + disk_io = disk.xpath("driver/@io")[0] except: pass try: - disk_discard = disk.xpath('driver/@discard')[0] + disk_discard = disk.xpath("driver/@discard")[0] except: pass try: - disk_zeroes = disk.xpath('driver/@detect_zeroes')[0] + disk_zeroes = disk.xpath("driver/@detect_zeroes")[0] except: pass - readonly = True if disk.xpath('readonly') else False - shareable = True if disk.xpath('shareable') else False - serial = disk.xpath('serial')[0].text if disk.xpath('serial') else None + readonly = True if disk.xpath("readonly") else False + shareable = True if disk.xpath("shareable") else False + serial = disk.xpath("serial")[0].text if disk.xpath("serial") else None try: vol = self.get_volume_by_path(src_file) @@ -454,25 +455,27 @@ class wvmInstance(wvmConnect): except libvirtError: volume = src_file except Exception as e: - print(f'Exception: {e}') + print(f"Exception: {e}") finally: - result.append({ - 'dev': dev, - 'bus': bus, - 'image': volume, - 'storage': storage, - 'path': src_file, - 'format': disk_format, - 'size': disk_size, - 'used': used_size, - 'cache': disk_cache, - 'io': disk_io, - 'discard': disk_discard, - 'detect_zeroes': disk_zeroes, - 'readonly': readonly, - 'shareable': shareable, - 'serial': serial - }) + result.append( + { + "dev": dev, + "bus": bus, + "image": volume, + "storage": storage, + "path": src_file, + "format": disk_format, + "size": disk_size, + "used": used_size, + "cache": disk_cache, + "io": disk_io, + "discard": disk_discard, + "detect_zeroes": disk_zeroes, + "readonly": readonly, + "shareable": shareable, + "serial": serial, + } + ) return result return util.get_xml_path(self._XMLDesc(0), func=disks) @@ -482,14 +485,14 @@ class wvmInstance(wvmConnect): result = [] dev = volume = storage = bus = None src_file = None - for media in doc.xpath('/domain/devices/disk'): - device = media.xpath('@device')[0] - if device == 'cdrom': + for media in doc.xpath("/domain/devices/disk"): + device = media.xpath("@device")[0] + if device == "cdrom": try: - dev = media.xpath('target/@dev')[0] - bus = media.xpath('target/@bus')[0] + dev = media.xpath("target/@dev")[0] + bus = media.xpath("target/@bus")[0] try: - src_file = media.xpath('source/@file')[0] + src_file = media.xpath("source/@file")[0] vol = self.get_volume_by_path(src_file) volume = vol.name() stg = vol.storagePoolLookupByVolume() @@ -500,18 +503,18 @@ class wvmInstance(wvmConnect): except: pass finally: - result.append({'dev': dev, 'image': volume, 'storage': storage, 'path': src_file, 'bus': bus}) + result.append({"dev": dev, "image": volume, "storage": storage, "path": src_file, "bus": bus}) return result return util.get_xml_path(self._XMLDesc(0), func=disks) def get_bootmenu(self): menu = util.get_xml_path(self._XMLDesc(0), "/domain/os/bootmenu/@enable") - return True if menu == 'yes' else False + return True if menu == "yes" else False def set_bootmenu(self, flag): tree = ElementTree.fromstring(self._XMLDesc(0)) - os = tree.find('os') + os = tree.find("os") menu = os.find("bootmenu") if menu is None: @@ -520,13 +523,13 @@ class wvmInstance(wvmConnect): menu = os.find("bootmenu") if flag == 0: # Disable - menu.attrib['enable'] = 'no' + menu.attrib["enable"] = "no" elif flag == 1: # Enable - menu.attrib['enable'] = 'yes' + menu.attrib["enable"] = "yes" elif flag == -1: # Remove os.remove(menu) else: - raise Exception('Unknown boot menu option, please choose one of 0:disable, 1:enable, -1:remove') + raise Exception("Unknown boot menu option, please choose one of 0:disable, 1:enable, -1:remove") xmldom = ElementTree.tostring(tree).decode() self._defineXML(xmldom) @@ -535,42 +538,42 @@ class wvmInstance(wvmConnect): boot_order = {} type = target = None tree = ElementTree.fromstring(self._XMLDesc(0)) - os = tree.find('os') - boot = os.findall('boot') + os = tree.find("os") + boot = os.findall("boot") for idx, b in enumerate(boot): - dev = b.get('dev') - if dev == 'hd': + dev = b.get("dev") + if dev == "hd": target = "disk" type = "file" - elif dev == 'fd': + elif dev == "fd": target = "floppy" type = "file" - elif dev == 'cdrom': + elif dev == "cdrom": target = "cdrom" type = "file" - elif dev == 'network': + elif dev == "network": target = "network" type = "network" boot_order[idx] = {"type": type, "dev": dev, "target": target} - devices = tree.find('devices') + devices = tree.find("devices") for dev in devices: dev_target = None - boot_dev = dev.find('boot') + boot_dev = dev.find("boot") if boot_dev is not None: - idx = boot_dev.get('order') - dev_type = dev.get('type') - dev_device = dev.get('device') + idx = boot_dev.get("order") + dev_type = dev.get("type") + dev_device = dev.get("device") - if dev_type == 'file': - dev_target = dev.find('target').get('dev') + if dev_type == "file": + dev_target = dev.find("target").get("dev") - elif dev_type == 'network': - dev_mac = dev.find('mac').get('address') + elif dev_type == "network": + dev_mac = dev.find("mac").get("address") dev_device = "network" dev_target = "nic-{}".format(dev_mac[9:]) - elif dev_type == 'usb': + elif dev_type == "usb": pass boot_order[int(idx) - 1] = {"type": dev_type, "dev": dev_device, "target": dev_target} @@ -583,14 +586,14 @@ class wvmInstance(wvmConnect): def remove_bootorder(): tree = ElementTree.fromstring(self._XMLDesc(0)) - os = tree.find('os') - boot = os.findall('boot') + os = tree.find("os") + boot = os.findall("boot") # Remove old style boot order for b in boot: os.remove(b) # Remove rest of them - for dev in tree.find('devices'): - boot_dev = dev.find('boot') + for dev in tree.find("devices"): + boot_dev = dev.find("boot") if boot_dev is not None: dev.remove(boot_dev) return tree @@ -599,36 +602,36 @@ class wvmInstance(wvmConnect): for idx, dev in devorder.items(): order = ElementTree.fromstring("".format(idx + 1)) - if dev['type'] == 'disk': + if dev["type"] == "disk": devices = tree.findall("./devices/disk[@device='disk']") for d in devices: - device = d.find("./target[@dev='{}']".format(dev['dev'])) + device = d.find("./target[@dev='{}']".format(dev["dev"])) if device is not None: d.append(order) - elif dev['type'] == 'cdrom': + elif dev["type"] == "cdrom": devices = tree.findall("./devices/disk[@device='cdrom']") for d in devices: - device = d.find("./target[@dev='{}']".format(dev['dev'])) + device = d.find("./target[@dev='{}']".format(dev["dev"])) if device is not None: d.append(order) - elif dev['type'] == 'network': + elif dev["type"] == "network": devices = tree.findall("./devices/interface[@type='network']") for d in devices: - device = d.find("mac[@address='{}']".format(dev['dev'])) + device = d.find("mac[@address='{}']".format(dev["dev"])) if device is not None: d.append(order) else: - raise Exception('Invalid Device Type for boot order') + raise Exception("Invalid Device Type for boot order") self._defineXML(ElementTree.tostring(tree).decode()) def mount_iso(self, dev, image): def attach_iso(dev, disk, vol): - if disk.get('device') == 'cdrom': + if disk.get("device") == "cdrom": for elm in disk: - if elm.tag == 'target': - if elm.get('dev') == dev: - src_media = ElementTree.Element('source') - src_media.set('file', vol.path()) + if elm.tag == "target": + if elm.get("dev") == dev: + src_media = ElementTree.Element("source") + src_media.set("file", vol.path()) disk.insert(2, src_media) return True @@ -641,7 +644,7 @@ class wvmInstance(wvmConnect): if image == img: vol = stg.storageVolLookupByName(image) tree = ElementTree.fromstring(self._XMLDesc(0)) - for disk in tree.findall('devices/disk'): + for disk in tree.findall("devices/disk"): if attach_iso(dev, disk, vol): break if self.get_status() == 1: @@ -654,14 +657,14 @@ class wvmInstance(wvmConnect): def umount_iso(self, dev, image): tree = ElementTree.fromstring(self._XMLDesc(0)) - for disk in tree.findall('devices/disk'): - if disk.get('device') == 'cdrom': + for disk in tree.findall("devices/disk"): + if disk.get("device") == "cdrom": for elm in disk: - if elm.tag == 'source': - if elm.get('file') == image: + if elm.tag == "source": + if elm.get("file") == image: src_media = elm - if elm.tag == 'target': - if elm.get('dev') == dev: + if elm.tag == "target": + if elm.get("dev") == dev: disk.remove(src_media) if self.get_status() == 1: xml_disk = ElementTree.tostring(disk).decode() @@ -671,44 +674,46 @@ class wvmInstance(wvmConnect): xmldom = ElementTree.tostring(tree).decode() self._defineXML(xmldom) - def attach_disk(self, - target_dev, - source, - target_bus='ide', - disk_type='file', - disk_device='disk', - driver_name='qemu', - driver_type='raw', - readonly=False, - shareable=False, - serial=None, - cache_mode=None, - io_mode=None, - discard_mode=None, - detect_zeroes_mode=None): + def attach_disk( + self, + target_dev, + source, + target_bus="ide", + disk_type="file", + disk_device="disk", + driver_name="qemu", + driver_type="raw", + readonly=False, + shareable=False, + serial=None, + cache_mode=None, + io_mode=None, + discard_mode=None, + detect_zeroes_mode=None, + ): - additionals = '' - if cache_mode is not None and cache_mode != 'default' and disk_device != 'cdrom': + additionals = "" + if cache_mode is not None and cache_mode != "default" and disk_device != "cdrom": additionals += f"cache='{cache_mode}' " - if io_mode is not None and io_mode != 'default': + if io_mode is not None and io_mode != "default": additionals += f"io='{io_mode}' " - if discard_mode is not None and discard_mode != 'default': + if discard_mode is not None and discard_mode != "default": additionals += f"discard='{discard_mode}' " - if detect_zeroes_mode is not None and detect_zeroes_mode != 'default': + if detect_zeroes_mode is not None and detect_zeroes_mode != "default": additionals += f"detect_zeroes='{detect_zeroes_mode}' " xml_disk = f"" - if disk_device == 'cdrom': + if disk_device == "cdrom": xml_disk += f"" - elif disk_device == 'disk': + elif disk_device == "disk": xml_disk += f"" xml_disk += f""" """ - if readonly or disk_device == 'cdrom': + if readonly or disk_device == "cdrom": xml_disk += """""" if shareable: xml_disk += """""" - if serial is not None and serial != 'None' and serial != '': + if serial is not None and serial != "None" and serial != "": xml_disk += f"""{serial}""" xml_disk += """""" if self.get_status() == 1: @@ -722,7 +727,7 @@ class wvmInstance(wvmConnect): disk_el = tree.xpath("./devices/disk/target[@dev='{}']".format(target_dev))[0].getparent() xml_disk = etree.tostring(disk_el).decode() - devices = tree.find('devices') + devices = tree.find("devices") devices.remove(disk_el) if self.get_status() == 1: @@ -731,29 +736,41 @@ class wvmInstance(wvmConnect): if self.get_status() == 5: self.instance.detachDeviceFlags(xml_disk, VIR_DOMAIN_AFFECT_CONFIG) - def edit_disk(self, target_dev, source, readonly, shareable, target_bus, serial, format, cache_mode, io_mode, discard_mode, - detect_zeroes_mode): + def edit_disk( + self, + target_dev, + source, + readonly, + shareable, + target_bus, + serial, + format, + cache_mode, + io_mode, + discard_mode, + detect_zeroes_mode, + ): tree = etree.fromstring(self._XMLDesc(0)) disk_el = tree.xpath("./devices/disk/target[@dev='{}']".format(target_dev))[0].getparent() - old_disk_type = disk_el.get('type') - old_disk_device = disk_el.get('device') - old_driver_name = disk_el.xpath('driver/@name')[0] - old_target_bus = disk_el.xpath('target/@bus')[0] + old_disk_type = disk_el.get("type") + old_disk_device = disk_el.get("device") + old_driver_name = disk_el.xpath("driver/@name")[0] + old_target_bus = disk_el.xpath("target/@bus")[0] - additionals = '' - if cache_mode is not None and cache_mode != 'default': + additionals = "" + if cache_mode is not None and cache_mode != "default": additionals += f"cache='{cache_mode}' " - if io_mode is not None and io_mode != 'default': + if io_mode is not None and io_mode != "default": additionals += f"io='{io_mode}' " - if discard_mode is not None and discard_mode != 'default': + if discard_mode is not None and discard_mode != "default": additionals += f"discard='{discard_mode}' " - if detect_zeroes_mode is not None and detect_zeroes_mode != 'default': + if detect_zeroes_mode is not None and detect_zeroes_mode != "default": additionals += f"detect_zeroes='{detect_zeroes_mode}' " xml_disk = f"" - if old_disk_device == 'cdrom': + if old_disk_device == "cdrom": xml_disk += f"" - elif old_disk_device == 'disk': + elif old_disk_device == "disk": xml_disk += f"" xml_disk += f""" @@ -762,7 +779,7 @@ class wvmInstance(wvmConnect): xml_disk += """""" if shareable: xml_disk += """""" - if serial is not None and serial != 'None' and serial != '': + if serial is not None and serial != "None" and serial != "": xml_disk += f"""{serial}""" xml_disk += """""" @@ -776,9 +793,9 @@ class wvmInstance(wvmConnect): time.sleep(1) cpu_use_now = self.instance.info()[4] diff_usage = cpu_use_now - cpu_use_ago - cpu_usage['cpu'] = 100 * diff_usage / (1 * nbcore * 10**9) + cpu_usage["cpu"] = 100 * diff_usage / (1 * nbcore * 10 ** 9) else: - cpu_usage['cpu'] = 0 + cpu_usage["cpu"] = 0 return cpu_usage def set_vcpu(self, cpu_id, enabled): @@ -814,38 +831,39 @@ class wvmInstance(wvmConnect): mem_usage = {} if self.get_status() == 1: mem_stats = self.instance.memoryStats() - rss = mem_stats['rss'] if 'rss' in mem_stats else 0 - total = mem_stats['actual'] if 'actual' in mem_stats else 0 + rss = mem_stats["rss"] if "rss" in mem_stats else 0 + total = mem_stats["actual"] if "actual" in mem_stats else 0 available = total - rss - if available < 0: available = 0 + if available < 0: + available = 0 - mem_usage['used'] = rss - mem_usage['total'] = total + mem_usage["used"] = rss + mem_usage["total"] = total else: - mem_usage['used'] = 0 - mem_usage['total'] = 0 + mem_usage["used"] = 0 + mem_usage["total"] = 0 return mem_usage def disk_usage(self): devices = [] dev_usage = [] tree = ElementTree.fromstring(self._XMLDesc(0)) - for disk in tree.findall('devices/disk'): - if disk.get('device') == 'disk': + for disk in tree.findall("devices/disk"): + if disk.get("device") == "disk": dev_file = None dev_bus = None network_disk = True for elm in disk: - if elm.tag == 'source': - if elm.get('protocol'): - dev_file = elm.get('protocol') + if elm.tag == "source": + if elm.get("protocol"): + dev_file = elm.get("protocol") network_disk = True - if elm.get('file'): - dev_file = elm.get('file') - if elm.get('dev'): - dev_file = elm.get('dev') - if elm.tag == 'target': - dev_bus = elm.get('dev') + if elm.get("file"): + dev_file = elm.get("file") + if elm.get("dev"): + dev_file = elm.get("dev") + if elm.tag == "target": + dev_bus = elm.get("dev") if (dev_file and dev_bus) is not None: if network_disk: dev_file = dev_bus @@ -862,7 +880,7 @@ class wvmInstance(wvmConnect): else: rd_diff_usage = 0 wr_diff_usage = 0 - dev_usage.append({'dev': dev[1], 'rd': rd_diff_usage, 'wr': wr_diff_usage}) + dev_usage.append({"dev": dev[1], "rd": rd_diff_usage, "wr": wr_diff_usage}) return dev_usage def net_usage(self): @@ -880,24 +898,24 @@ class wvmInstance(wvmConnect): tx_use_now = self.instance.interfaceStats(dev)[4] rx_diff_usage = (rx_use_now - rx_use_ago) * 8 tx_diff_usage = (tx_use_now - tx_use_ago) * 8 - dev_usage.append({'dev': i, 'rx': rx_diff_usage, 'tx': tx_diff_usage}) + dev_usage.append({"dev": i, "rx": rx_diff_usage, "tx": tx_diff_usage}) else: for i, dev in enumerate(self.get_net_devices()): - dev_usage.append({'dev': i, 'rx': 0, 'tx': 0}) + dev_usage.append({"dev": i, "rx": 0, "tx": 0}) return dev_usage def get_telnet_port(self): telnet_port = None service_port = None tree = ElementTree.fromstring(self._XMLDesc(0)) - for console in tree.findall('devices/console'): - if console.get('type') == 'tcp': + for console in tree.findall("devices/console"): + if console.get("type") == "tcp": for elm in console: - if elm.tag == 'source': - if elm.get('service'): - service_port = elm.get('service') - if elm.tag == 'protocol': - if elm.get('type') == 'telnet': + if elm.tag == "source": + if elm.get("service"): + service_port = elm.get("service") + if elm.tag == "protocol": + if elm.get("type") == "telnet": if service_port is not None: telnet_port = service_port return telnet_port @@ -948,7 +966,7 @@ class wvmInstance(wvmConnect): current_type = self.get_console_type() if current_type == console_type: return True - if console_type == '': + if console_type == "": return False xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE) root = ElementTree.fromstring(xml) @@ -957,7 +975,7 @@ class wvmInstance(wvmConnect): except SyntaxError: # Little fix for old version ElementTree graphic = root.find("devices/graphics") - graphic.set('type', console_type) + graphic.set("type", console_type) newxml = ElementTree.tostring(root).decode() self._defineXML(newxml) @@ -969,7 +987,9 @@ class wvmInstance(wvmConnect): def get_console_websocket_port(self): console_type = self.get_console_type() - websocket_port = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics[@type='%s']/@websocket" % console_type) + websocket_port = util.get_xml_path( + self._XMLDesc(0), "/domain/devices/graphics[@type='%s']/@websocket" % console_type + ) return websocket_port def get_console_passwd(self): @@ -987,10 +1007,10 @@ class wvmInstance(wvmConnect): if graphic is None: return False if passwd: - graphic.set('passwd', passwd) + graphic.set("passwd", passwd) else: try: - graphic.attrib.pop('passwd') + graphic.attrib.pop("passwd") except: pass newxml = ElementTree.tostring(root).decode() @@ -1005,18 +1025,18 @@ class wvmInstance(wvmConnect): except SyntaxError: # Little fix for old version ElementTree graphic = root.find("devices/graphics") - if keymap != 'auto': - graphic.set('keymap', keymap) + if keymap != "auto": + graphic.set("keymap", keymap) else: try: - graphic.attrib.pop('keymap') + graphic.attrib.pop("keymap") except: pass newxml = ElementTree.tostring(root).decode() self._defineXML(newxml) def get_console_keymap(self): - return util.get_xml_path(self._XMLDesc(VIR_DOMAIN_XML_SECURE), "/domain/devices/graphics/@keymap") or '' + return util.get_xml_path(self._XMLDesc(VIR_DOMAIN_XML_SECURE), "/domain/devices/graphics/@keymap") or "" def get_video_model(self): """ :return only primary video card""" @@ -1024,8 +1044,8 @@ class wvmInstance(wvmConnect): tree = etree.fromstring(xml) video_models = tree.xpath("/domain/devices/video/model") for model in video_models: - if model.get('primary') == 'yes' or len(video_models) == 1: - return model.get('type') + if model.get("primary") == "yes" or len(video_models) == 1: + return model.get("type") def set_video_model(self, model): """ Changes only primary video card""" @@ -1034,7 +1054,7 @@ class wvmInstance(wvmConnect): video_models = tree.xpath("/domain/devices/video/model") video_xml = "".format(model) for model in video_models: - if model.get('primary') == 'yes' or len(video_models) == 1: + if model.get("primary") == "yes" or len(video_models) == 1: parent = model.getparent() parent.remove(model) parent.append(etree.fromstring(video_xml)) @@ -1051,9 +1071,9 @@ class wvmInstance(wvmConnect): xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE) tree = etree.fromstring(xml) - vcpu_elem = tree.find('vcpu') + vcpu_elem = tree.find("vcpu") vcpu_elem.text = vcpu - vcpu_elem.set('current', cur_vcpu) + vcpu_elem.set("current", cur_vcpu) new_xml = etree.tostring(tree).decode() self._defineXML(new_xml) @@ -1076,9 +1096,9 @@ class wvmInstance(wvmConnect): xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE) tree = etree.fromstring(xml) - mem_elem = tree.find('memory') + mem_elem = tree.find("memory") mem_elem.text = str(memory) - cur_mem_elem = tree.find('currentMemory') + cur_mem_elem = tree.find("currentMemory") cur_mem_elem.text = str(cur_memory) new_xml = etree.tostring(tree).decode() @@ -1092,9 +1112,9 @@ class wvmInstance(wvmConnect): tree = etree.fromstring(xml) for disk in disks: - source_dev = disk['path'] + source_dev = disk["path"] vol = self.get_volume_by_path(source_dev) - vol.resize(disk['size_new']) + vol.resize(disk["size_new"]) new_xml = etree.tostring(tree).decode() self._defineXML(new_xml) @@ -1110,14 +1130,14 @@ class wvmInstance(wvmConnect): except: pass for img in stg.listVolumes(): - if img.lower().endswith('.iso'): + if img.lower().endswith(".iso"): iso.append(img) return iso def delete_all_disks(self): disks = self.get_disk_devices() for disk in disks: - vol = self.get_volume_by_path(disk.get('path')) + vol = self.get_volume_by_path(disk.get("path")) vol.delete(0) def _snapshotCreateXML(self, xml, flag): @@ -1127,7 +1147,10 @@ class wvmInstance(wvmConnect): xml = """ %s shutoff - %d""" % (name, time.time()) + %d""" % ( + name, + time.time(), + ) xml += self._XMLDesc(VIR_DOMAIN_XML_SECURE) xml += """0 """ @@ -1139,7 +1162,7 @@ class wvmInstance(wvmConnect): for snapshot in snapshot_list: snap = self.instance.snapshotLookupByName(snapshot, 0) snap_time_create = util.get_xml_path(snap.getXMLDesc(0), "/domainsnapshot/creationTime") - snapshots.append({'date': datetime.fromtimestamp(int(snap_time_create)), 'name': snapshot}) + snapshots.append({"date": datetime.fromtimestamp(int(snap_time_create)), "name": snapshot}) return snapshots def snapshot_delete(self, snapshot): @@ -1164,29 +1187,29 @@ class wvmInstance(wvmConnect): return mac # if mac does not contain ":", try to split into tuples and join with ":" n = 2 - mac_tuples = [mac[i:i + n] for i in range(0, len(mac), n)] - return ':'.join(mac_tuples) + mac_tuples = [mac[i : i + n] for i in range(0, len(mac), n)] + return ":".join(mac_tuples) def clone_instance(self, clone_data): clone_dev_path = [] xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE) tree = etree.fromstring(xml) - name = tree.find('name') - name.text = clone_data['name'] - uuid = tree.find('uuid') + name = tree.find("name") + name.text = clone_data["name"] + uuid = tree.find("uuid") tree.remove(uuid) options = { - 'title': clone_data.get('clone-title', ''), - 'description': clone_data.get('clone-description', ''), + "title": clone_data.get("clone-title", ""), + "description": clone_data.get("clone-description", ""), } self._set_options(tree, options) src_nvram_path = self.get_nvram() if src_nvram_path: # Change XML for nvram - nvram = tree.find('os/nvram') + nvram = tree.find("os/nvram") nvram.getparent().remove(nvram) # NVRAM CLONE: create pool if nvram is not in a pool. then clone it @@ -1197,40 +1220,40 @@ class wvmInstance(wvmConnect): self.get_volume_by_path(src_nvram_path) except libvirtError: stg_conn = self.get_wvmStorages() - stg_conn.create_storage('dir', nvram_pool_name, None, nvram_dir) + stg_conn.create_storage("dir", nvram_pool_name, None, nvram_dir) new_nvram_name = f"{clone_data['name']}_VARS" nvram_stg = self.get_wvmStorage(nvram_pool_name) - nvram_stg.clone_volume(src_nvram_name, new_nvram_name, file_suffix='fd') + nvram_stg.clone_volume(src_nvram_name, new_nvram_name, file_suffix="fd") - for num, net in enumerate(tree.findall('devices/interface')): - elm = net.find('mac') - mac_address = self.fix_mac(clone_data['clone-net-mac-' + str(num)]) - elm.set('address', mac_address) + for num, net in enumerate(tree.findall("devices/interface")): + elm = net.find("mac") + mac_address = self.fix_mac(clone_data["clone-net-mac-" + str(num)]) + elm.set("address", mac_address) - for disk in tree.findall('devices/disk'): - if disk.get('device') == 'disk': - elm = disk.find('target') - device_name = elm.get('dev') + for disk in tree.findall("devices/disk"): + if disk.get("device") == "disk": + elm = disk.find("target") + device_name = elm.get("dev") if device_name: - target_file = clone_data['disk-' + device_name] + target_file = clone_data["disk-" + device_name] try: - meta_prealloc = clone_data['meta-' + device_name] + meta_prealloc = clone_data["meta-" + device_name] except: meta_prealloc = False - elm.set('dev', device_name) + elm.set("dev", device_name) - elm = disk.find('source') - source_file = elm.get('file') + elm = disk.find("source") + source_file = elm.get("file") if source_file: clone_dev_path.append(source_file) clone_path = os.path.join(os.path.dirname(source_file), target_file) - elm.set('file', clone_path) + elm.set("file", clone_path) vol = self.get_volume_by_path(source_file) vol_format = util.get_xml_path(vol.XMLDesc(0), "/volume/target/format/@type") - if vol_format == 'qcow2' and meta_prealloc: + if vol_format == "qcow2" and meta_prealloc: meta_prealloc = True vol_clone_xml = f""" @@ -1256,11 +1279,11 @@ class wvmInstance(wvmConnect): stg = vol.storagePoolLookupByVolume() stg.createXMLFrom(vol_clone_xml, vol, meta_prealloc) - source_protocol = elm.get('protocol') - if source_protocol == 'rbd': - source_name = elm.get('name') + source_protocol = elm.get("protocol") + if source_protocol == "rbd": + source_name = elm.get("name") clone_name = "%s/%s" % (os.path.dirname(source_name), target_file) - elm.set('name', clone_name) + elm.set("name", clone_name) vol = self.get_volume_by_path(source_name) vol_format = util.get_xml_path(vol.XMLDesc(0), "/volume/target/format/@type") @@ -1277,10 +1300,10 @@ class wvmInstance(wvmConnect): stg = vol.storagePoolLookupByVolume() stg.createXMLFrom(vol_clone_xml, vol, meta_prealloc) - source_dev = elm.get('dev') + source_dev = elm.get("dev") if source_dev: clone_path = os.path.join(os.path.dirname(source_dev), target_file) - elm.set('dev', clone_path) + elm.set("dev", clone_path) vol = self.get_volume_by_path(source_dev) stg = vol.storagePoolLookupByVolume() @@ -1293,10 +1316,10 @@ class wvmInstance(wvmConnect): self._defineXML(ElementTree.tostring(tree).decode()) - return self.get_instance(clone_data['name']).UUIDString() + return self.get_instance(clone_data["name"]).UUIDString() - def get_bridge_name(self, source, source_type='net'): - if source_type == 'iface': + def get_bridge_name(self, source, source_type="net"): + if source_type == "iface": iface = self.get_iface(source) bridge_name = iface.name() else: @@ -1307,28 +1330,28 @@ class wvmInstance(wvmConnect): bridge_name = None return bridge_name - def add_network(self, mac_address, source, source_type='net', model='virtio', nwfilter=None): - forward_mode = '' - if source_type != 'iface': + def add_network(self, mac_address, source, source_type="net", model="virtio", nwfilter=None): + forward_mode = "" + if source_type != "iface": forward_mode = self.get_network_forward(source) - if forward_mode in ['nat', 'isolated', 'routed']: - interface_type = 'network' - elif forward_mode == '': - interface_type = 'direct' + if forward_mode in ["nat", "isolated", "routed"]: + interface_type = "network" + elif forward_mode == "": + interface_type = "direct" else: if self.get_bridge_name(source, source_type) is None: - interface_type = 'network' + interface_type = "network" else: - interface_type = 'bridge' + interface_type = "bridge" xml_iface = f""" """ - if interface_type == 'network': + if interface_type == "network": xml_iface += f"""""" - elif interface_type == 'direct': - if source_type == 'net': + elif interface_type == "direct": + if source_type == "net": xml_iface += f"""""" else: xml_iface += f"""""" @@ -1348,9 +1371,9 @@ class wvmInstance(wvmConnect): def delete_network(self, mac_address): tree = ElementTree.fromstring(self._XMLDesc(0)) - for interface in tree.findall('devices/interface'): - source = interface.find('mac') - if source.get('address', '') == mac_address: + for interface in tree.findall("devices/interface"): + source = interface.find("mac") + if source.get("address", "") == mac_address: new_xml = ElementTree.tostring(interface).decode() if self.get_status() == 1: @@ -1362,55 +1385,58 @@ class wvmInstance(wvmConnect): def change_network(self, network_data): xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE) tree = ElementTree.fromstring(xml) - for num, interface in enumerate(tree.findall('devices/interface')): - net_mac = network_data.get('net-mac-' + str(num)) - if net_mac is None: continue - net_source = network_data.get('net-source-' + str(num)) - net_source_type = network_data.get('net-source-' + str(num) + '-type') - net_filter = network_data.get('net-nwfilter-' + str(num)) - net_model = network_data.get('net-model-' + str(num)) + for num, interface in enumerate(tree.findall("devices/interface")): + net_mac = network_data.get("net-mac-" + str(num)) + if net_mac is None: + continue + net_source = network_data.get("net-source-" + str(num)) + net_source_type = network_data.get("net-source-" + str(num) + "-type") + net_filter = network_data.get("net-nwfilter-" + str(num)) + net_model = network_data.get("net-model-" + str(num)) - source = interface.find('source') - if interface.get('type') == 'bridge': + source = interface.find("source") + if interface.get("type") == "bridge": bridge_name = self.get_bridge_name(net_source, net_source_type) - source.set('bridge', bridge_name) - elif interface.get('type') in ['network', 'direct']: - if net_source_type == 'net': - source.set('network', net_source) - elif net_source_type == 'iface': - source.set('dev', net_source) + source.set("bridge", bridge_name) + elif interface.get("type") in ["network", "direct"]: + if net_source_type == "net": + source.set("network", net_source) + elif net_source_type == "iface": + source.set("dev", net_source) else: raise libvirtError("Unknown network type: {}".format(net_source_type)) else: - raise libvirtError("Unknown network type: {}".format(interface.get('type'))) + raise libvirtError("Unknown network type: {}".format(interface.get("type"))) - source = interface.find('model') - if net_model != 'default': - source.attrib['type'] = net_model + source = interface.find("model") + if net_model != "default": + source.attrib["type"] = net_model else: interface.remove(source) - source = interface.find('mac') - source.set('address', net_mac) - source = interface.find('filterref') + source = interface.find("mac") + source.set("address", net_mac) + source = interface.find("filterref") if net_filter: - if source is not None: source.set('filter', net_filter) + if source is not None: + source.set("filter", net_filter) else: element = ElementTree.Element("filterref") - element.attrib['filter'] = net_filter + element.attrib["filter"] = net_filter interface.append(element) else: - if source is not None: interface.remove(source) + if source is not None: + interface.remove(source) new_xml = ElementTree.tostring(tree).decode() self._defineXML(new_xml) def set_link_state(self, mac_address, state): tree = etree.fromstring(self._XMLDesc(0)) - for interface in tree.findall('devices/interface'): - source = interface.find('mac') - if source.get('address') == mac_address: - link = interface.find('link') + for interface in tree.findall("devices/interface"): + source = interface.find("mac") + if source.get("address") == mac_address: + link = interface.find("link") if link is not None: interface.remove(link) link_el = etree.Element("link") @@ -1424,9 +1450,9 @@ class wvmInstance(wvmConnect): self.instance.updateDeviceFlags(new_xml, VIR_DOMAIN_AFFECT_CONFIG) def _set_options(self, tree, options): - for o in ['title', 'description']: + for o in ["title", "description"]: option = tree.find(o) - option_value = options.get(o, '').strip() + option_value = options.get(o, "").strip() if not option_value: if option is not None: tree.remove(option) @@ -1456,29 +1482,33 @@ class wvmInstance(wvmConnect): for q in qos: bound_list = list() - mac = q.xpath('mac/@address') - band = q.find('bandwidth') + mac = q.xpath("mac/@address") + band = q.find("bandwidth") if band is not None: - in_qos = band.find('inbound') + in_qos = band.find("inbound") if in_qos is not None: - in_av = in_qos.get('average') - in_peak = in_qos.get('peak') - in_burst = in_qos.get('burst') - in_floor = in_qos.get('floor') - bound_list.append({ - 'direction': 'inbound', - 'average': in_av, - 'peak': in_peak, - 'floor': in_floor, - 'burst': in_burst - }) + in_av = in_qos.get("average") + in_peak = in_qos.get("peak") + in_burst = in_qos.get("burst") + in_floor = in_qos.get("floor") + bound_list.append( + { + "direction": "inbound", + "average": in_av, + "peak": in_peak, + "floor": in_floor, + "burst": in_burst, + } + ) - out_qos = band.find('outbound') + out_qos = band.find("outbound") if out_qos is not None: - out_av = out_qos.get('average') - out_peak = out_qos.get('peak') - out_burst = out_qos.get('burst') - bound_list.append({'direction': 'outbound', 'average': out_av, 'peak': out_peak, 'burst': out_burst}) + out_av = out_qos.get("average") + out_peak = out_qos.get("peak") + out_burst = out_qos.get("burst") + bound_list.append( + {"direction": "outbound", "average": out_av, "peak": out_peak, "burst": out_burst} + ) qos_values[mac[0]] = bound_list return qos_values @@ -1488,7 +1518,7 @@ class wvmInstance(wvmConnect): elif direction == "outbound": xml = f"" else: - raise Exception('Direction must be inbound or outbound') + raise Exception("Direction must be inbound or outbound") tree = etree.fromstring(self._XMLDesc(0)) @@ -1497,7 +1527,7 @@ class wvmInstance(wvmConnect): if cur_mac.get("address") == mac: interface = cur_mac.getparent() - band = interface.find('bandwidth') + band = interface.find("bandwidth") if band is None: xml = "" + xml + "" interface.append(etree.fromstring(xml)) @@ -1517,7 +1547,7 @@ class wvmInstance(wvmConnect): for direct in tree.xpath("/domain/devices/interface/bandwidth/{}".format(direction)): band_el = direct.getparent() interface_el = band_el.getparent() # parent bandwidth,its parent is interface - parent_mac = interface_el.xpath('mac/@address') + parent_mac = interface_el.xpath("mac/@address") if parent_mac[0] == mac: band_el.remove(direct) @@ -1551,7 +1581,7 @@ class wvmInstance(wvmConnect): """ Return agent channel object if it is defined. """ - for channel in doc.xpath('/domain/devices/channel'): + for channel in doc.xpath("/domain/devices/channel"): ch_type = channel.get("type") target = channel.find("target") target_name = target.get("name") @@ -1570,7 +1600,7 @@ class wvmInstance(wvmConnect): dev = self.get_guest_agent() if dev is not None: states = dev.xpath("target/@state") - state = states[0] if len(states) > 0 else '' + state = states[0] if len(states) > 0 else "" if state == "connected": return True return False diff --git a/vrtManager/interface.py b/vrtManager/interface.py index 149c600..b6e7c56 100644 --- a/vrtManager/interface.py +++ b/vrtManager/interface.py @@ -1,8 +1,8 @@ from xml.etree import ElementTree -from libvirt import VIR_INTERFACE_XML_INACTIVE -from vrtManager.connection import wvmConnect -from vrtManager import util +from libvirt import VIR_INTERFACE_XML_INACTIVE +from vrtManager import util +from vrtManager.connection import wvmConnect class wvmInterfaces(wvmConnect): @@ -12,36 +12,37 @@ class wvmInterfaces(wvmConnect): mac = iface.MACString() itype = util.get_xml_path(xml, "/interface/@type") state = iface.isActive() - return {'name': name, 'type': itype, 'state': state, 'mac': mac} + return {"name": name, "type": itype, "state": state, "mac": mac} def define_iface(self, xml, flag=0): self.wvm.interfaceDefineXML(xml, flag) - def create_iface(self, name, itype, mode, netdev, ipv4_type, ipv4_addr, ipv4_gw, - ipv6_type, ipv6_addr, ipv6_gw, stp, delay): + def create_iface( + self, name, itype, mode, netdev, ipv4_type, ipv4_addr, ipv4_gw, ipv6_type, ipv6_addr, ipv6_gw, stp, delay + ): xml = f""" """ - if ipv4_type == 'dhcp': + if ipv4_type == "dhcp": xml += """ """ - if ipv4_type == 'static': - address, prefix = ipv4_addr.split('/') + if ipv4_type == "static": + address, prefix = ipv4_addr.split("/") xml += f""" """ - if ipv6_type == 'dhcp': + if ipv6_type == "dhcp": xml += """ """ - if ipv6_type == 'static': - address, prefix = ipv6_addr.split('/') + if ipv6_type == "static": + address, prefix = ipv6_addr.split("/") xml += f""" """ - if itype == 'bridge': + if itype == "bridge": xml += f""" """ @@ -85,9 +86,9 @@ class wvmInterface(wvmConnect): xml = self._XMLDesc(VIR_INTERFACE_XML_INACTIVE) ipaddr = util.get_xml_path(xml, "/interface/protocol[@family='ipv4']/ip/@address") if ipaddr: - return 'static' + return "static" else: - return 'dhcp' + return "dhcp" except: return None @@ -98,16 +99,16 @@ class wvmInterface(wvmConnect): if not int_ipv4_ip or not int_ipv4_mask: return None else: - return int_ipv4_ip + '/' + int_ipv4_mask + return int_ipv4_ip + "/" + int_ipv4_mask def get_ipv6_type(self): try: xml = self._XMLDesc(VIR_INTERFACE_XML_INACTIVE) ipaddr = util.get_xml_path(xml, "/interface/protocol[@family='ipv6']/ip/@address") if ipaddr: - return 'static' + return "static" else: - return 'dhcp' + return "dhcp" except: return None @@ -118,15 +119,15 @@ class wvmInterface(wvmConnect): if not int_ipv6_ip or not int_ipv6_mask: return None else: - return int_ipv6_ip + '/' + int_ipv6_mask + return int_ipv6_ip + "/" + int_ipv6_mask def get_bridge(self): bridge = None - if self.get_type() == 'bridge': + if self.get_type() == "bridge": bridge = util.get_xml_path(self._XMLDesc(), "/interface/bridge/interface/@name") for iface in self.get_bridge_slave_ifaces(): - if iface.get('state') == 'up' and iface.get('speed') is not 'unknown': - bridge = iface.get('name') + if iface.get("state") == "up" and iface.get("speed") != "unknown": + bridge = iface.get("name") return bridge return bridge else: @@ -134,20 +135,20 @@ class wvmInterface(wvmConnect): def get_bridge_slave_ifaces(self): ifaces = list() - if self.get_type() == 'bridge': + if self.get_type() == "bridge": tree = ElementTree.fromstring(self._XMLDesc()) for iface in tree.findall("./bridge/"): address = state = speed = None - name = iface.get('name') - if_type = iface.get('type') - link = iface.find('link') + name = iface.get("name") + if_type = iface.get("type") + link = iface.find("link") if link is not None: - state = link.get('state') - speed = link.get('speed') - mac = iface.find('mac') + state = link.get("state") + speed = link.get("speed") + mac = iface.find("mac") if mac is not None: - address = mac.get('address') - ifaces.append({'name': name, 'type': if_type, 'state': state, 'speed': speed, 'mac': address}) + address = mac.get("address") + ifaces.append({"name": name, "type": if_type, "state": state, "speed": speed, "mac": address}) return ifaces else: return None diff --git a/vrtManager/network.py b/vrtManager/network.py index 8ab2fc5..80b405b 100644 --- a/vrtManager/network.py +++ b/vrtManager/network.py @@ -1,11 +1,17 @@ +from libvirt import ( + VIR_NETWORK_SECTION_IP_DHCP_HOST, + VIR_NETWORK_UPDATE_AFFECT_CONFIG, + VIR_NETWORK_UPDATE_AFFECT_LIVE, + VIR_NETWORK_UPDATE_COMMAND_ADD_LAST, + VIR_NETWORK_UPDATE_COMMAND_DELETE, + VIR_NETWORK_UPDATE_COMMAND_MODIFY, + libvirtError, +) from lxml import etree -from libvirt import libvirtError -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_AFFECT_LIVE, VIR_NETWORK_UPDATE_AFFECT_CONFIG from vrtManager import util -from vrtManager.IPy import IP from vrtManager.connection import wvmConnect +from vrtManager.IPy import IP + def network_size(subnet, dhcp=None): """ @@ -17,7 +23,7 @@ def network_size(subnet, dhcp=None): if addr.version() == 4: dhcp_pool = [addr[2].strCompressed(), addr[addr.len() - 2].strCompressed()] if addr.version() == 6: - mask = mask.lstrip('/') if '/' in mask else mask + mask = mask.lstrip("/") if "/" in mask else mask dhcp_pool = [IP(addr[0].strCompressed() + hex(256)), IP(addr[0].strCompressed() + hex(512 - 1))] if dhcp: return gateway, mask, dhcp_pool @@ -26,7 +32,6 @@ def network_size(subnet, dhcp=None): class wvmNetworks(wvmConnect): - def get_networks_info(self): get_networks = self.get_networks() networks = [] @@ -39,44 +44,55 @@ class wvmNetworks(wvmConnect): net_bridge = util.get_xml_path(net.XMLDesc(0), "/network/forward/interface/@dev") net_forward = util.get_xml_path(net.XMLDesc(0), "/network/forward/@mode") - networks.append({'name': network, 'status': net_status, - 'device': net_bridge, 'forward': net_forward}) + networks.append({"name": network, "status": net_status, "device": net_bridge, "forward": net_forward}) return networks def define_network(self, xml): self.wvm.networkDefineXML(xml) - def create_network(self, name, forward, - ipv4, gateway, mask, dhcp4, - ipv6, gateway6, prefix6, dhcp6, - bridge, openvswitch, fixed=False): + def create_network( + self, + name, + forward, + ipv4, + gateway, + mask, + dhcp4, + ipv6, + gateway6, + prefix6, + dhcp6, + bridge, + openvswitch, + fixed=False, + ): xml = f""" {name}""" - if forward in ['nat', 'route', 'bridge']: + if forward in ["nat", "route", "bridge"]: xml += f"""""" - if forward == 'macvtap': + if forward == "macvtap": xml += f""" """ else: xml += """""" if openvswitch is True: xml += """""" - if forward not in ['bridge', 'macvtap']: + if forward not in ["bridge", "macvtap"]: if ipv4: xml += f"""""" if dhcp4: xml += f""" """ if fixed: - fist_oct = int(dhcp4[0].strip().split('.')[3]) - last_oct = int(dhcp4[1].strip().split('.')[3]) + fist_oct = int(dhcp4[0].strip().split(".")[3]) + last_oct = int(dhcp4[1].strip().split(".")[3]) for ip in range(fist_oct, last_oct + 1): xml += f"""""" xml += """""" @@ -144,23 +160,23 @@ class wvmNetwork(wvmConnect): if util.get_xml_path(xml, "/network/ip") is None: return ip_networks tree = etree.fromstring(xml) - ips = tree.findall('.ip') + ips = tree.findall(".ip") for ip in ips: - address_str = ip.get('address') - netmask_str = ip.get('netmask') - prefix = ip.get('prefix') - family = ip.get('family', 'ipv4') - base = 32 if family == 'ipv4' else 128 + address_str = ip.get("address") + netmask_str = ip.get("netmask") + prefix = ip.get("prefix") + family = ip.get("family", "ipv4") + base = 32 if family == "ipv4" else 128 if prefix: prefix = int(prefix) - binstr = ((prefix * "1") + ((base - prefix) * "0")) + binstr = (prefix * "1") + ((base - prefix) * "0") netmask_str = str(IP(int(binstr, base=2))) if netmask_str: netmask = IP(netmask_str) gateway = IP(address_str) network = IP(gateway.int() & netmask.int()) - netmask_str = netmask_str if family == 'ipv4' else str(prefix) + netmask_str = netmask_str if family == "ipv4" else str(prefix) ret = IP(str(network) + "/" + netmask_str) else: ret = IP(str(address_str)) @@ -178,12 +194,12 @@ class wvmNetwork(wvmConnect): forward_dev = util.get_xml_path(xml, "/network/forward/@dev") return [fw, forward_dev] - def get_dhcp_range(self, family='ipv4'): + def get_dhcp_range(self, family="ipv4"): xml = self._XMLDesc(0) - if family == 'ipv4': + if family == "ipv4": dhcpstart = util.get_xml_path(xml, "/network/ip[not(@family='ipv6')]/dhcp/range[1]/@start") dhcpend = util.get_xml_path(xml, "/network/ip[not(@family='ipv6')]/dhcp/range[1]/@end") - if family == 'ipv6': + if family == "ipv6": dhcpstart = util.get_xml_path(xml, "/network/ip[@family='ipv6']/dhcp/range[1]/@start") dhcpend = util.get_xml_path(xml, "/network/ip[@family='ipv6']/dhcp/range[1]/@end") @@ -192,13 +208,13 @@ class wvmNetwork(wvmConnect): return [IP(dhcpstart), IP(dhcpend)] - def get_dhcp_range_start(self, family='ipv4'): + def get_dhcp_range_start(self, family="ipv4"): dhcp = self.get_dhcp_range(family) if not dhcp: return None return dhcp[0] - def get_dhcp_range_end(self, family='ipv4'): + def get_dhcp_range_end(self, family="ipv4"): dhcp = self.get_dhcp_range(family) if not dhcp: return None @@ -211,74 +227,77 @@ class wvmNetwork(wvmConnect): return True return bool(util.get_xml_path(xml, "/network/ip/dhcp/bootp/@file")) - def get_dhcp_host_addr(self, family='ipv4'): + def get_dhcp_host_addr(self, family="ipv4"): result = list() tree = etree.fromstring(self._XMLDesc(0)) for ipdhcp in tree.findall("./ip"): - if family == 'ipv4': - if ipdhcp.get('family') is None: - hosts = ipdhcp.findall('./dhcp/host') + if family == "ipv4": + if ipdhcp.get("family") is None: + hosts = ipdhcp.findall("./dhcp/host") for host in hosts: - host_ip = host.get('ip') - mac = host.get('mac') - name = host.get('name', '') - result.append({'ip': host_ip, 'mac': mac, 'name': name}) + host_ip = host.get("ip") + mac = host.get("mac") + name = host.get("name", "") + result.append({"ip": host_ip, "mac": mac, "name": name}) return result else: continue - if family == 'ipv6': + if family == "ipv6": hosts = tree.xpath("./ip[@family='ipv6']/dhcp/host") for host in hosts: - host_ip = host.get('ip') - host_id = host.get('id') - name = host.get('name', '') - result.append({'ip': host_ip, 'id': host_id, 'name': name}) + host_ip = host.get("ip") + host_id = host.get("id") + name = host.get("name", "") + result.append({"ip": host_ip, "id": host_id, "name": name}) 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(): tree = etree.fromstring(self._XMLDesc(0)) - if family == 'ipv4': + if family == "ipv4": dhcp_range = tree.xpath("./ip[not(@family='ipv6')]/dhcp/range") - if family == 'ipv6': + if family == "ipv6": dhcp_range = tree.xpath("./ip[@family='ipv6']/dhcp/range") - dhcp_range[0].set('start', range_start) - dhcp_range[0].set('end', range_end) + dhcp_range[0].set("start", range_start) + dhcp_range[0].set("end", range_end) self.wvm.networkDefineXML(etree.tostring(tree).decode()) - def delete_fixed_address(self, ip, family='ipv4'): + def delete_fixed_address(self, ip, family="ipv4"): tree = etree.fromstring(self._XMLDesc(0)) - if family == 'ipv4': + if family == "ipv4": hosts = tree.xpath("/network/ip[not(@family='ipv6')]/dhcp/host") parent_index = self.parent_count - 2 - if family == 'ipv6': + if family == "ipv6": hosts = tree.xpath("/network/ip[@family='ipv6']/dhcp/host") parent_index = self.parent_count - 1 for h in hosts: - if h.get('ip') == ip: - if family == 'ipv4': - new_xml = ''.format(h.get('mac'), h.get('name'), ip) - if family == 'ipv6': - new_xml = ''.format(h.get('id'), h.get('name'), ip) + if h.get("ip") == ip: + if family == "ipv4": + new_xml = ''.format(h.get("mac"), h.get("name"), ip) + if family == "ipv6": + new_xml = ''.format(h.get("id"), h.get("name"), ip) - self.update(VIR_NETWORK_UPDATE_COMMAND_DELETE, VIR_NETWORK_SECTION_IP_DHCP_HOST, - new_xml, - parent_index, - VIR_NETWORK_UPDATE_AFFECT_LIVE | VIR_NETWORK_UPDATE_AFFECT_CONFIG) + self.update( + VIR_NETWORK_UPDATE_COMMAND_DELETE, + VIR_NETWORK_SECTION_IP_DHCP_HOST, + new_xml, + parent_index, + VIR_NETWORK_UPDATE_AFFECT_LIVE | VIR_NETWORK_UPDATE_AFFECT_CONFIG, + ) break - def modify_fixed_address(self, name, address, mac_duid, family='ipv4'): + def modify_fixed_address(self, name, address, mac_duid, family="ipv4"): tree = etree.fromstring(self._XMLDesc(0)) - if family == 'ipv4': - new_xml = ''.format(mac_duid, 'name="' + name + '"' if name else '', IP(address)) + if family == "ipv4": + new_xml = ''.format(mac_duid, 'name="' + name + '"' if name else "", IP(address)) hosts = tree.xpath("./ip[not(@family='ipv6')]/dhcp/host") - compare_var = 'mac' + compare_var = "mac" parent_index = self.parent_count - 2 - if family == 'ipv6': - new_xml = ''.format(mac_duid, 'name="' + name + '"' if name else '', IP(address)) + if family == "ipv6": + new_xml = ''.format(mac_duid, 'name="' + name + '"' if name else "", IP(address)) hosts = tree.xpath("./ip[@family='ipv6']/dhcp/host") - compare_var = 'id' + compare_var = "id" parent_index = self.parent_count - 1 new_host_xml = etree.fromstring(new_xml) @@ -288,17 +307,25 @@ class wvmNetwork(wvmConnect): host = h break if host is None: - self.update(VIR_NETWORK_UPDATE_COMMAND_ADD_LAST, VIR_NETWORK_SECTION_IP_DHCP_HOST, new_xml, - parent_index, - VIR_NETWORK_UPDATE_AFFECT_LIVE | VIR_NETWORK_UPDATE_AFFECT_CONFIG) + self.update( + VIR_NETWORK_UPDATE_COMMAND_ADD_LAST, + VIR_NETWORK_SECTION_IP_DHCP_HOST, + new_xml, + parent_index, + VIR_NETWORK_UPDATE_AFFECT_LIVE | VIR_NETWORK_UPDATE_AFFECT_CONFIG, + ) else: # change the host - if host.get('name') == new_host_xml.get('name') and host.get('ip') == new_host_xml.get('ip'): + if host.get("name") == new_host_xml.get("name") and host.get("ip") == new_host_xml.get("ip"): return False else: - self.update(VIR_NETWORK_UPDATE_COMMAND_MODIFY, VIR_NETWORK_SECTION_IP_DHCP_HOST, new_xml, - parent_index, - VIR_NETWORK_UPDATE_AFFECT_LIVE | VIR_NETWORK_UPDATE_AFFECT_CONFIG) + self.update( + VIR_NETWORK_UPDATE_COMMAND_MODIFY, + VIR_NETWORK_SECTION_IP_DHCP_HOST, + new_xml, + parent_index, + VIR_NETWORK_UPDATE_AFFECT_LIVE | VIR_NETWORK_UPDATE_AFFECT_CONFIG, + ) def get_qos(self): qos_values = dict() @@ -307,19 +334,19 @@ class wvmNetwork(wvmConnect): if qos: qos = qos[0] - in_qos = qos.find('inbound') + in_qos = qos.find("inbound") if in_qos is not None: - in_av = in_qos.get('average') - in_peak = in_qos.get('peak') - in_burst = in_qos.get('burst') - qos_values['inbound'] = {'average': in_av, 'peak': in_peak, 'burst': in_burst} + in_av = in_qos.get("average") + in_peak = in_qos.get("peak") + in_burst = in_qos.get("burst") + qos_values["inbound"] = {"average": in_av, "peak": in_peak, "burst": in_burst} - out_qos = qos.find('outbound') + out_qos = qos.find("outbound") if out_qos is not None: - out_av = out_qos.get('average') - out_peak = out_qos.get('peak') - out_burst = out_qos.get('burst') - qos_values['outbound'] = {'average': out_av, 'peak': out_peak, 'burst': out_burst} + out_av = out_qos.get("average") + out_peak = out_qos.get("peak") + out_burst = out_qos.get("burst") + qos_values["outbound"] = {"average": out_av, "peak": out_peak, "burst": out_burst} return qos_values def set_qos(self, direction, average, peak, burst): @@ -328,7 +355,7 @@ class wvmNetwork(wvmConnect): elif direction == "outbound": xml = f"" else: - raise Exception('Direction must be inbound or outbound') + raise Exception("Direction must be inbound or outbound") tree = etree.fromstring(self._XMLDesc(0)) diff --git a/vrtManager/nwfilters.py b/vrtManager/nwfilters.py index f0a89a5..627e571 100644 --- a/vrtManager/nwfilters.py +++ b/vrtManager/nwfilters.py @@ -1,4 +1,5 @@ from xml.etree import ElementTree + from vrtManager.connection import wvmConnect @@ -7,7 +8,7 @@ class wvmNWFilters(wvmConnect): nwfilter = self.get_nwfilter(name) xml = nwfilter.XMLDesc(0) uuid = nwfilter.UUIDString() - return {'name': name, 'uuid': uuid, 'xml': xml} + return {"name": name, "uuid": uuid, "xml": xml} def create_nwfilter(self, xml): self.wvm.nwfilterDefineXML(xml) @@ -16,8 +17,8 @@ class wvmNWFilters(wvmConnect): nwfilter = self.get_nwfilter(name) if nwfilter: tree = ElementTree.fromstring(nwfilter.XMLDesc(0)) - tree.set('name', cln_name) - uuid = tree.find('uuid') + tree.set("name", cln_name) + uuid = tree.find("uuid") tree.remove(uuid) self.create_nwfilter(ElementTree.tostring(tree).decode()) @@ -41,7 +42,7 @@ class wvmNWFilter(wvmConnect): def get_xml(self): tree = ElementTree.fromstring(self._XMLDesc(0)) - uuid = tree.find('uuid') + uuid = tree.find("uuid") tree.remove(uuid) return ElementTree.tostring(tree).decode() @@ -49,7 +50,7 @@ class wvmNWFilter(wvmConnect): refs = [] tree = ElementTree.fromstring(self._XMLDesc(0)) for ref in tree.findall("./filterref"): - refs.append(ref.get('filter')) + refs.append(ref.get("filter")) return refs def get_rules(self): @@ -57,10 +58,10 @@ class wvmNWFilter(wvmConnect): tree = ElementTree.fromstring(self._XMLDesc(0)) for r in tree.findall("./rule"): - rule_action = r.get('action') - rule_direction = r.get('direction') - rule_priority = r.get('priority') - rule_statematch = r.get('statematch') + rule_action = r.get("action") + rule_direction = r.get("direction") + rule_priority = r.get("priority") + rule_statematch = r.get("statematch") rule_directives = r.find("./") if rule_directives is not None: @@ -71,7 +72,7 @@ class wvmNWFilter(wvmConnect): "direction": rule_direction, "priority": rule_priority, "statematch": rule_statematch, - "directives": rule_directives + "directives": rule_directives, } rules.append(rule_info) @@ -81,7 +82,7 @@ class wvmNWFilter(wvmConnect): def delete_ref(self, name): tree = ElementTree.fromstring(self._XMLDesc(0)) for ref in tree.findall("./filterref"): - if name == ref.get('filter'): + if name == ref.get("filter"): tree.remove(ref) break return ElementTree.tostring(tree).decode() @@ -89,7 +90,9 @@ class wvmNWFilter(wvmConnect): def delete_rule(self, action, direction, priority): tree = ElementTree.fromstring(self._XMLDesc(0)) - rule_tree = tree.findall("./rule[@action='%s'][@direction='%s'][@priority='%s']" % (action, direction, priority)) + rule_tree = tree.findall( + "./rule[@action='%s'][@direction='%s'][@priority='%s']" % (action, direction, priority) + ) if rule_tree: tree.remove(rule_tree[0]) @@ -98,7 +101,7 @@ class wvmNWFilter(wvmConnect): def add_ref(self, name): tree = ElementTree.fromstring(self._XMLDesc(0)) element = ElementTree.Element("filterref") - element.attrib['filter'] = name + element.attrib["filter"] = name tree.append(element) return ElementTree.tostring(tree).decode() @@ -106,19 +109,21 @@ class wvmNWFilter(wvmConnect): tree = ElementTree.fromstring(self._XMLDesc(0)) rule = ElementTree.fromstring(xml) - rule_action = rule.get('action') - rule_direction = rule.get('direction') - rule_priority = rule.get('priority') + rule_action = rule.get("action") + rule_direction = rule.get("direction") + rule_priority = rule.get("priority") rule_directives = rule.find("./") - rule_tree = tree.findall("./rule[@action='%s'][@direction='%s'][@priority='%s']" % (rule_action, rule_direction, rule_priority)) + rule_tree = tree.findall( + "./rule[@action='%s'][@direction='%s'][@priority='%s']" % (rule_action, rule_direction, rule_priority) + ) if rule_tree: rule_tree[0].append(rule_directives) else: element = ElementTree.Element("rule") - element.attrib['action'] = rule_action - element.attrib['direction'] = rule_direction - element.attrib['priority'] = rule_priority + element.attrib["action"] = rule_action + element.attrib["direction"] = rule_direction + element.attrib["priority"] = rule_priority element.append(rule_directives) tree.append(element) diff --git a/vrtManager/rwlock.py b/vrtManager/rwlock.py index 2ee82f9..a32903f 100644 --- a/vrtManager/rwlock.py +++ b/vrtManager/rwlock.py @@ -11,11 +11,9 @@ found at: http://code.activestate.com/recipes/502283-read-write-lock-class-rlock # Imports # ------- - from threading import Condition, Lock, currentThread from time import time - # Read write lock # --------------- @@ -138,9 +136,7 @@ class ReadWriteLock(object): # else also wants to upgrade, there is no way we can do # this except if one of us releases all his read locks. # Signal this to user. - raise ValueError( - "Inevitable dead lock, denying write lock" - ) + raise ValueError("Inevitable dead lock, denying write lock") upgradewriter = True self.__upgradewritercount = self.__readers.pop(me) else: diff --git a/vrtManager/secrets.py b/vrtManager/secrets.py index de7b3f4..c877282 100644 --- a/vrtManager/secrets.py +++ b/vrtManager/secrets.py @@ -1,4 +1,5 @@ import base64 + from vrtManager.connection import wvmConnect @@ -6,12 +7,12 @@ class wvmSecrets(wvmConnect): def create_secret(self, ephemeral, private, secret_type, data): xml = f""" """ - if secret_type == 'ceph': + if secret_type == "ceph": xml += f"""{data}""" - if secret_type == 'volume': + if secret_type == "volume": xml += f"""{data}""" - if secret_type == 'iscsi': - xml += f"""{data}""" + if secret_type == "iscsi": + xml += f"""{data}""" xml += """ """ self.wvm.secretDefineXML(xml) diff --git a/vrtManager/storage.py b/vrtManager/storage.py index 7726b95..85eafb0 100644 --- a/vrtManager/storage.py +++ b/vrtManager/storage.py @@ -16,13 +16,7 @@ class wvmStorages(wvmConnect): stg_vol = None stg_size = stg.info()[1] storages.append( - { - "name": pool, - "status": stg_status, - "type": stg_type, - "volumes": stg_vol, - "size": stg_size - } + {"name": pool, "status": stg_status, "type": stg_type, "volumes": stg_vol, "size": stg_size} ) return storages @@ -103,12 +97,7 @@ class wvmStorage(wvmConnect): return self.pool.name() def get_status(self): - status = [ - "Not running", - "Initializing pool, not available", - "Running normally", - "Running degraded" - ] + status = ["Not running", "Initializing pool, not available", "Running normally", "Running degraded"] try: return status[self.pool.info()[0]] except ValueError: @@ -217,12 +206,12 @@ class wvmStorage(wvmConnect): "name": volname, "size": self.get_volume_size(volname), "allocation": self.get_volume_allocation(volname), - "type": self.get_volume_type(volname) + "type": self.get_volume_type(volname), } ) return vol_list - def create_volume(self, name, size, vol_fmt='qcow2', metadata=False, disk_owner_uid=0, disk_owner_gid=0): + def create_volume(self, name, size, vol_fmt="qcow2", metadata=False, disk_owner_uid=0, disk_owner_gid=0): size = int(size) * 1073741824 storage_type = self.get_type() alloc = size @@ -258,7 +247,17 @@ class wvmStorage(wvmConnect): self._createXML(xml, metadata) return name - def clone_volume(self, name, target_file, vol_fmt=None, metadata=False, mode='0644', file_suffix='img', disk_owner_uid=0, disk_owner_gid=0): + def clone_volume( + self, + name, + target_file, + vol_fmt=None, + metadata=False, + mode="0644", + file_suffix="img", + disk_owner_uid=0, + disk_owner_gid=0, + ): vol = self.get_volume(name) if not vol_fmt: vol_fmt = self.get_volume_type(name) @@ -266,10 +265,10 @@ class wvmStorage(wvmConnect): storage_type = self.get_type() if storage_type == "dir": if vol_fmt in ["qcow", "qcow2"]: - target_file += '.' + vol_fmt + target_file += "." + vol_fmt else: - suffix = '.' + file_suffix - target_file += suffix if len(suffix) > 1 else '' + suffix = "." + file_suffix + target_file += suffix if len(suffix) > 1 else "" xml = f""" diff --git a/vrtManager/util.py b/vrtManager/util.py index 88403f5..c3bee0f 100644 --- a/vrtManager/util.py +++ b/vrtManager/util.py @@ -1,8 +1,8 @@ import random -import string import re -import lxml.etree as etree +import string import libvirt +import lxml.etree as etree def is_kvm_available(xml): @@ -18,10 +18,8 @@ def randomMAC(): # qemu MAC oui = [0x52, 0x54, 0x00] - mac = oui + [random.randint(0x00, 0xff), - random.randint(0x00, 0xff), - random.randint(0x00, 0xff)] - return ':'.join(map(lambda x: "%02x" % x, mac)) + mac = oui + [random.randint(0x00, 0xFF), random.randint(0x00, 0xFF), random.randint(0x00, 0xFF)] + return ":".join(map(lambda x: "%02x" % x, mac)) def randomUUID(): @@ -29,18 +27,17 @@ def randomUUID(): u = [random.randint(0, 255) for ignore in range(0, 16)] u[6] = (u[6] & 0x0F) | (4 << 4) u[8] = (u[8] & 0x3F) | (2 << 6) - return "-".join(["%02x" * 4, "%02x" * 2, "%02x" * 2, "%02x" * 2, - "%02x" * 6]) % tuple(u) + return "-".join(["%02x" * 4, "%02x" * 2, "%02x" * 2, "%02x" * 2, "%02x" * 6]) % tuple(u) def randomPasswd(length=12, alphabet=string.ascii_letters + string.digits): """Generate a random password""" - return ''.join([random.choice(alphabet) for i in range(length)]) + return "".join([random.choice(alphabet) for i in range(length)]) def get_max_vcpus(conn, type=None): """@param conn: libvirt connection to poll for max possible vcpus - @type type: optional guest type (kvm, etc.)""" + @type type: optional guest type (kvm, etc.)""" if type is None: type = conn.getType() try: @@ -57,7 +54,7 @@ def xml_escape(str): str = str.replace("&", "&") str = str.replace("'", "'") - str = str.replace("\"", """) + str = str.replace('"', """) str = str.replace("<", "<") str = str.replace(">", ">") return str @@ -109,7 +106,7 @@ def get_xpath(doc, path): if ret is not None: if isinstance(ret, list): if len(ret) >= 1: - if hasattr(ret[0], 'text'): + if hasattr(ret[0], "text"): result = ret[0].text else: result = ret[0] @@ -146,11 +143,11 @@ def validate_uuid(val): raise ValueError( "UUID must be a 32-digit hexadecimal number. It may take " "the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx or may " - "omit hyphens altogether.") + "omit hyphens altogether." + ) - else: # UUID had no dashes, so add them in - val = (val[0:8] + "-" + val[8:12] + "-" + val[12:16] + - "-" + val[16:20] + "-" + val[20:32]) + else: # UUID had no dashes, so add them in + val = val[0:8] + "-" + val[8:12] + "-" + val[12:16] + "-" + val[16:20] + "-" + val[20:32] return val @@ -177,7 +174,8 @@ UEFI_ARCH_PATTERNS = { r".*OVMF_CODE\.fd", # RHEL r".*ovmf-x64/OVMF.*\.fd", # gerd's firmware repo r".*ovmf-x86_64-.*", # SUSE - r".*ovmf.*", ".*OVMF.*", # generic attempt at a catchall + r".*ovmf.*", + ".*OVMF.*", # generic attempt at a catchall ], "aarch64": [ r".*AAVMF_CODE\.fd", # RHEL diff --git a/webvirtcloud/common_tags.py b/webvirtcloud/common_tags.py index 0b43d01..7197800 100644 --- a/webvirtcloud/common_tags.py +++ b/webvirtcloud/common_tags.py @@ -1,29 +1,30 @@ -from django import template import re +from django import template + register = template.Library() @register.simple_tag def app_active(request, app_name): if request.resolver_match.app_name == app_name: - return 'active' - return '' + return "active" + return "" @register.simple_tag def view_active(request, view_name): if request.resolver_match.view_name == view_name: - return 'active' - return '' + return "active" + return "" @register.simple_tag def class_active(request, pattern): if re.search(pattern, request.path): # Not sure why 'class="active"' returns class=""active"" - return 'active' - return '' + return "active" + return "" @register.simple_tag diff --git a/webvirtcloud/middleware.py b/webvirtcloud/middleware.py index 902edd1..fe2d039 100644 --- a/webvirtcloud/middleware.py +++ b/webvirtcloud/middleware.py @@ -17,5 +17,5 @@ class ExceptionMiddleware: request, _("libvirt Error - %(exception)s") % {"exception": exception}, ) - return render(request, '500.html', status=500) + return render(request, "500.html", status=500) # TODO: check connecting to host via VPN diff --git a/webvirtcloud/settings-dev.py b/webvirtcloud/settings-dev.py index 25b9733..990ed60 100644 --- a/webvirtcloud/settings-dev.py +++ b/webvirtcloud/settings-dev.py @@ -20,9 +20,7 @@ MIDDLEWARE += [ ] # DebugToolBar -INTERNAL_IPS = ( - "127.0.0.1", -) +INTERNAL_IPS = ("127.0.0.1",) DEBUG_TOOLBAR_CONFIG = { "INTERCEPT_REDIRECTS": False, } diff --git a/webvirtcloud/settings.py.template b/webvirtcloud/settings.py.template index 6dd0b2a..d2d4577 100644 --- a/webvirtcloud/settings.py.template +++ b/webvirtcloud/settings.py.template @@ -8,102 +8,102 @@ import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -SECRET_KEY = '' +SECRET_KEY = "" DEBUG = False -ALLOWED_HOSTS = ['*'] +ALLOWED_HOSTS = ["*"] # Application definition INSTALLED_APPS = [ - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'bootstrap4', - 'django_icons', - 'django_otp', - 'django_otp.plugins.otp_totp', - 'accounts', - 'admin', - 'appsettings', - 'computes', - 'console', - 'datasource', - 'networks', - 'instances', - 'interfaces', - 'nwfilters', - 'storages', - 'secrets', - 'logs', - 'qr_code', + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "bootstrap4", + "django_icons", + "django_otp", + "django_otp.plugins.otp_totp", + "accounts", + "admin", + "appsettings", + "computes", + "console", + "datasource", + "networks", + "instances", + "interfaces", + "nwfilters", + "storages", + "secrets", + "logs", + "qr_code", ] MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.locale.LocaleMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django_otp.middleware.OTPMiddleware', - 'login_required.middleware.LoginRequiredMiddleware', - 'django.contrib.auth.middleware.RemoteUserMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'appsettings.middleware.AppSettingsMiddleware', - 'webvirtcloud.middleware.ExceptionMiddleware', + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.locale.LocaleMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django_otp.middleware.OTPMiddleware", + "login_required.middleware.LoginRequiredMiddleware", + "django.contrib.auth.middleware.RemoteUserMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", + "appsettings.middleware.AppSettingsMiddleware", + "webvirtcloud.middleware.ExceptionMiddleware", ] -ROOT_URLCONF = 'webvirtcloud.urls' +ROOT_URLCONF = "webvirtcloud.urls" TEMPLATES = [ { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [ - os.path.join(BASE_DIR, 'templates'), + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [ + os.path.join(BASE_DIR, "templates"), ], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', - 'appsettings.context_processors.app_settings', + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + "appsettings.context_processors.app_settings", ], - 'libraries': { - 'common_tags': 'webvirtcloud.common_tags', + "libraries": { + "common_tags": "webvirtcloud.common_tags", }, }, }, ] -WSGI_APPLICATION = 'webvirtcloud.wsgi.application' +WSGI_APPLICATION = "webvirtcloud.wsgi.application" # Database # https://docs.djangoproject.com/en/3.0/ref/settings/#databases DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": os.path.join(BASE_DIR, "db.sqlite3"), } } AUTHENTICATION_BACKENDS = [ - 'django.contrib.auth.backends.ModelBackend', + "django.contrib.auth.backends.ModelBackend", ] -LOGIN_URL = '/accounts/login/' +LOGIN_URL = "/accounts/login/" -LOGOUT_REDIRECT_URL = '/accounts/login/' +LOGOUT_REDIRECT_URL = "/accounts/login/" -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = "en-us" -TIME_ZONE = 'UTC' +TIME_ZONE = "UTC" USE_I18N = True @@ -111,32 +111,21 @@ USE_L10N = True USE_TZ = True -STATIC_URL = '/static/' +STATIC_URL = "/static/" STATICFILES_DIRS = [ os.path.join(BASE_DIR, "static"), ] LOCALE_PATHS = [ - 'locale/', + "locale/", ] LOGGING = { "version": 1, "disable_existing_loggers": False, - "handlers": { - "mail_admins": { - "level": "ERROR", - "class": "django.utils.log.AdminEmailHandler" - } - }, - "loggers": { - "django.request": { - "handlers": ["mail_admins"], - "level": "ERROR", - "propagate": True - } - }, + "handlers": {"mail_admins": {"level": "ERROR", "class": "django.utils.log.AdminEmailHandler"}}, + "loggers": {"django.request": {"handlers": ["mail_admins"], "level": "ERROR", "propagate": True}}, } # @@ -147,7 +136,7 @@ LOGGING = { WS_PORT = 6080 # Websock host -WS_HOST = '0.0.0.0' +WS_HOST = "0.0.0.0" # Websock public port - 80 or 443 if reverse-proxy, else 6080 WS_PUBLIC_PORT = 6080 @@ -156,22 +145,53 @@ WS_PUBLIC_PORT = 6080 WS_PUBLIC_HOST = None # Websock public path -WS_PUBLIC_PATH = '/novncd/' +WS_PUBLIC_PATH = "/novncd/" # Websock Certificate for SSL WS_CERT = None # List of console listen addresses QEMU_CONSOLE_LISTEN_ADDRESSES = ( - ('127.0.0.1', 'Localhost'), - ('0.0.0.0', 'All interfaces'), + ("127.0.0.1", "Localhost"), + ("0.0.0.0", "All interfaces"), ) # List taken from http://qemu.weilnetz.de/qemu-doc.html#sec_005finvocation -QEMU_KEYMAPS = ['ar', 'da', 'de', 'de-ch', 'en-gb', 'en-us', 'es', 'et', 'fi', - 'fo', 'fr', 'fr-be', 'fr-ca', 'fr-ch', 'hr', 'hu', 'is', 'it', - 'ja', 'lt', 'lv', 'mk', 'nl', 'nl-be', 'no', 'pl', 'pt', - 'pt-br', 'ru', 'sl', 'sv', 'th', 'tr'] +QEMU_KEYMAPS = [ + "ar", + "da", + "de", + "de-ch", + "en-gb", + "en-us", + "es", + "et", + "fi", + "fo", + "fr", + "fr-be", + "fr-ca", + "fr-ch", + "hr", + "hu", + "is", + "it", + "ja", + "lt", + "lv", + "mk", + "nl", + "nl-be", + "no", + "pl", + "pt", + "pt-br", + "ru", + "sl", + "sv", + "th", + "tr", +] # Keepalive interval and count for libvirt connections LIBVIRT_KEEPALIVE_INTERVAL = 5 @@ -183,5 +203,4 @@ SHOW_PROFILE_EDIT_PASSWORD = True OTP_ENABLED = False -LOGIN_REQUIRED_IGNORE_VIEW_NAMES = ['accounts:email_otp'] - +LOGIN_REQUIRED_IGNORE_VIEW_NAMES = ["accounts:email_otp"] diff --git a/webvirtcloud/urls.py b/webvirtcloud/urls.py index 24854ca..42785ac 100644 --- a/webvirtcloud/urls.py +++ b/webvirtcloud/urls.py @@ -1,21 +1,20 @@ -from django.conf import settings -from django.urls import include, path - from appsettings.views import appsettings from console.views import console +from django.conf import settings +from django.urls import include, path from instances.views import index urlpatterns = [ - path('', index, name='index'), - path('admin/', include(('admin.urls', 'admin'), namespace='admin')), - path('accounts/', include('accounts.urls')), - path('appsettings/', appsettings, name='appsettings'), - path('computes/', include('computes.urls')), - path('console/', console, name='console'), - path('datasource/', include('datasource.urls')), - path('instances/', include('instances.urls')), - path('i18n/', include('django.conf.urls.i18n')), - path('logs/', include('logs.urls')), + path("", index, name="index"), + path("admin/", include(("admin.urls", "admin"), namespace="admin")), + path("accounts/", include("accounts.urls")), + path("appsettings/", appsettings, name="appsettings"), + path("computes/", include("computes.urls")), + path("console/", console, name="console"), + path("datasource/", include("datasource.urls")), + path("instances/", include("instances.urls")), + path("i18n/", include("django.conf.urls.i18n")), + path("logs/", include("logs.urls")), ] if settings.DEBUG: @@ -23,7 +22,7 @@ if settings.DEBUG: import debug_toolbar urlpatterns += [ - path('__debug__/', include(debug_toolbar.urls)), + path("__debug__/", include(debug_toolbar.urls)), ] except ImportError: pass diff --git a/webvirtcloud/wsgi.py b/webvirtcloud/wsgi.py index 53925ed..d444f71 100644 --- a/webvirtcloud/wsgi.py +++ b/webvirtcloud/wsgi.py @@ -11,6 +11,6 @@ import os from django.core.wsgi import get_wsgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'webvirtcloud.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "webvirtcloud.settings") application = get_wsgi_application() diff --git a/webvirtcloud/wsgi_custom.py b/webvirtcloud/wsgi_custom.py index f423187..089153e 100644 --- a/webvirtcloud/wsgi_custom.py +++ b/webvirtcloud/wsgi_custom.py @@ -12,13 +12,7 @@ import sys from django.core.wsgi import get_wsgi_application # execfile('/srv/webvirtcloud/venv/bin/activate_this.py', dict(__file__='/srv/webvirtcloud/venv/bin/activate_this.py')) -exec( - compile( - open("/srv/webvirtcloud/venv/bin/activate", "rb").read(), - "/srv/webvirtcloud/venv/bin/activate", - "exec" - ) -) +exec(compile(open("/srv/webvirtcloud/venv/bin/activate", "rb").read(), "/srv/webvirtcloud/venv/bin/activate", "exec")) sys.path.append("/srv/webvirtcloud")