1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2024-11-01 03:54:15 +00:00

Merge pull request #555 from catborise/master

code black format
This commit is contained in:
catborise 2022-11-14 09:17:45 +03:00 committed by GitHub
commit 7db75784c6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 411 additions and 395 deletions

View file

@ -30,9 +30,10 @@ def create_admin(sender, **kwargs):
"""
Create initial admin user
"""
from accounts.models import UserAttributes
from django.contrib.auth.models import User
from accounts.models import UserAttributes
plan = kwargs.get("plan", [])
for migration, rolled_back in plan:
if (

View file

@ -173,8 +173,7 @@ def email_otp(request):
send_email_with_otp(user, device)
messages.success(
request,
_("OTP Sent to %(email)s") % {"email": form.cleaned_data["email"]}
request, _("OTP Sent to %(email)s") % {"email": form.cleaned_data["email"]}
)
return redirect("accounts:login")
@ -195,12 +194,8 @@ def admin_email_otp(request, user_id):
if user.email != "":
send_email_with_otp(user, device)
messages.success(
request,
_("OTP QR code was emailed to user %(user)s") % {"user": user}
request, _("OTP QR code was emailed to user %(user)s") % {"user": user}
)
else:
messages.error(
request,
_("User email not set, failed to send QR code")
)
messages.error(request, _("User email not set, failed to send QR code"))
return redirect("accounts:account", user.id)

View file

@ -1,3 +1,5 @@
from accounts.models import Instance, UserAttributes, UserInstance
from appsettings.settings import app_settings
from django.conf import settings
from django.contrib import messages
from django.contrib.auth import update_session_auth_hash
@ -6,9 +8,6 @@ from django.contrib.auth.models import Group, User
from django.core.paginator import Paginator
from django.shortcuts import get_object_or_404, redirect, render
from django.utils.translation import gettext_lazy as _
from accounts.models import UserAttributes, UserInstance, Instance
from appsettings.settings import app_settings
from logs.models import Logs
from . import forms
@ -149,8 +148,7 @@ def user_update_password(request, pk):
user = form.save()
update_session_auth_hash(request, user) # Important!
messages.success(
request,
_("Password changed for %(user)s") % {"user": user.username}
request, _("Password changed for %(user)s") % {"user": user.username}
)
return redirect("admin:user_list")
else:

View file

@ -1,11 +1,6 @@
from rest_framework import serializers
from computes.models import Compute
from vrtManager.connection import (
CONN_SOCKET,
CONN_SSH,
CONN_TCP,
CONN_TLS,
)
from rest_framework import serializers
from vrtManager.connection import CONN_SOCKET, CONN_SSH, CONN_TCP, CONN_TLS
class ComputeSerializer(serializers.ModelSerializer):

View file

@ -1,10 +1,9 @@
from computes.models import Compute
from rest_framework import viewsets
from rest_framework import permissions
from vrtManager.create import wvmCreate
from .serializers import ComputeSerializer
from rest_framework import permissions, viewsets
from rest_framework.response import Response
from vrtManager.create import wvmCreate
from .serializers import ComputeSerializer
class ComputeViewSet(viewsets.ModelViewSet):

View file

@ -12,4 +12,6 @@ def refresh_instance_database(compute):
names = Instance.objects.filter(compute=compute).values_list("name", flat=True)
for domain in domains:
if domain.name() not in names:
Instance( compute=compute, name=domain.name(), uuid=domain.UUIDString()).save()
Instance(
compute=compute, name=domain.name(), uuid=domain.UUIDString()
).save()

View file

@ -1,20 +1,12 @@
import json
from admin.decorators import superuser_only
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 admin.decorators import superuser_only
from computes.forms import (
SocketComputeForm,
SshComputeForm,
TcpComputeForm,
TlsComputeForm,
)
from computes.models import Compute
from instances.models import Instance
from libvirt import libvirtError
from vrtManager.connection import (
CONN_SOCKET,
CONN_SSH,
@ -25,6 +17,14 @@ from vrtManager.connection import (
)
from vrtManager.hostdetails import wvmHostDetails
from computes.forms import (
SocketComputeForm,
SshComputeForm,
TcpComputeForm,
TlsComputeForm,
)
from computes.models import Compute
from . import utils
@ -45,7 +45,8 @@ def overview(request, compute_id):
compute = get_object_or_404(Compute, pk=compute_id)
status = (
"true"
if connection_manager.host_is_up(compute.type, compute.hostname) is True else "false"
if connection_manager.host_is_up(compute.type, compute.hostname) is True
else "false"
)
conn = wvmHostDetails(
@ -82,9 +83,7 @@ def instances(request, compute_id):
)
return render(
request,
"computes/instances.html",
{"compute": compute, "instances": instances}
request, "computes/instances.html", {"compute": compute, "instances": instances}
)
@ -139,30 +138,9 @@ def compute_graph(request, compute_id):
:param compute_id:
:return:
"""
compute = get_object_or_404(Compute, pk=compute_id)
try:
conn = wvmHostDetails(
compute.hostname,
compute.login,
compute.password,
compute.type,
)
current_time = timezone.now().strftime("%H:%M:%S")
cpu_usage = conn.get_cpu_usage()
mem_usage = conn.get_memory_usage()
conn.close()
except libvirtError:
cpu_usage = {"usage": 0}
mem_usage = {"usage": 0}
current_time = 0
comp_mgr = ComputeManager(compute_id)
data = comp_mgr.compute_graph()
data = json.dumps(
{
"cpudata": cpu_usage["usage"],
"memdata": mem_usage,
"timeline": current_time,
}
)
response = HttpResponse()
response["Content-Type"] = "text/javascript"
response.write(data)
@ -178,17 +156,87 @@ def get_compute_disk_buses(request, compute_id, arch, machine, disk):
:param disk:
:return:
"""
data = dict()
compute = get_object_or_404(Compute, pk=compute_id)
try:
conn = wvmConnect(
compute.hostname,
compute.login,
compute.password,
compute.type,
comp_mgr = ComputeManager(compute_id)
return HttpResponse(comp_mgr.get_disk_buses(arch, machine, disk))
def get_compute_machine_types(request, compute_id, arch):
"""
:param request:
:param compute_id:
:param arch:
:return:
"""
comp_mgr = ComputeManager(compute_id)
return HttpResponse(comp_mgr.get_machine_types(arch))
def get_compute_video_models(request, compute_id, arch, machine):
"""
:param request:
:param compute_id:
:param arch:
:param machine:
:return:
"""
comp_mgr = ComputeManager(compute_id)
return HttpResponse(comp_mgr.get_video_models(arch, machine))
def get_dom_capabilities(request, compute_id, arch, machine):
"""
:param request:
:param compute_id:
:param arch:
:param machine:
:return:
"""
comp_mgr = ComputeManager(compute_id)
return HttpResponse(comp_mgr.get_dom_capabilities(arch, machine))
class ComputeManager:
def __init__(self, compute_id):
self.compute = get_object_or_404(Compute, pk=compute_id)
self.conn = wvmConnect(
self.compute.hostname,
self.compute.login,
self.compute.password,
self.compute.type,
)
disk_device_types = conn.get_disk_device_types(arch, machine)
def get_video_models(self, arch, machine):
data = dict()
try:
data["videos"] = self.conn.get_video_models(arch, machine)
except libvirtError:
pass
return json.dumps(data)
def get_dom_capabilities(self, arch, machine):
data = dict()
try:
data["videos"] = self.conn.get_disk_device_types(arch, machine)
data["bus"] = self.conn.get_disk_device_types(arch, machine)
except libvirtError:
pass
return json.dumps(data)
def get_machine_types(self, arch):
data = dict()
try:
data["machines"] = self.conn.get_machine_types(arch)
except libvirtError:
pass
return json.dumps(data)
def get_disk_buses(self, arch, machine, disk):
data = dict()
try:
disk_device_types = self.conn.get_disk_device_types(arch, machine)
if disk in disk_device_types:
if disk == "disk":
@ -202,76 +250,29 @@ def get_compute_disk_buses(request, compute_id, arch, machine, disk):
except libvirtError:
pass
return HttpResponse(json.dumps(data))
return json.dumps(data)
def get_compute_machine_types(request, compute_id, arch):
"""
:param request:
:param compute_id:
:param arch:
:return:
"""
data = dict()
def compute_graph(self):
try:
compute = get_object_or_404(Compute, pk=compute_id)
conn = wvmConnect(
compute.hostname,
compute.login,
compute.password,
compute.type,
conn = wvmHostDetails(
self.compute.hostname,
self.compute.login,
self.compute.password,
self.compute.type,
)
data["machines"] = conn.get_machine_types(arch)
current_time = timezone.now().strftime("%H:%M:%S")
cpu_usage = conn.get_cpu_usage()
mem_usage = conn.get_memory_usage()
conn.close()
except libvirtError:
pass
cpu_usage = {"usage": 0}
mem_usage = {"usage": 0}
current_time = 0
return HttpResponse(json.dumps(data))
def get_compute_video_models(request, compute_id, arch, machine):
"""
:param request:
:param compute_id:
:param arch:
:param machine:
:return:
"""
data = dict()
try:
compute = get_object_or_404(Compute, pk=compute_id)
conn = wvmConnect(
compute.hostname,
compute.login,
compute.password,
compute.type,
return json.dumps(
{
"cpudata": cpu_usage["usage"],
"memdata": mem_usage,
"timeline": current_time,
}
)
data["videos"] = conn.get_video_models(arch, machine)
except libvirtError:
pass
return HttpResponse(json.dumps(data))
def get_dom_capabilities(request, compute_id, arch, machine):
"""
:param request:
:param compute_id:
:param arch:
:param machine:
:return:
"""
data = dict()
try:
compute = get_object_or_404(Compute, pk=compute_id)
conn = wvmConnect(
compute.hostname,
compute.login,
compute.password,
compute.type,
)
data["videos"] = conn.get_disk_device_types(arch, machine)
data["bus"] = conn.get_disk_device_types(arch, machine)
except libvirtError:
pass
return HttpResponse(json.dumps(data))

View file

@ -1,15 +1,13 @@
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 django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404, render
from libvirt import libvirtError
from vrtManager.instance import wvmInstance
OS_VERSIONS = ["latest", ""]
OS_UUID = "iid-dswebvirtcloud"
@ -100,11 +98,7 @@ def get_vdi_url(request, compute_id, vname):
try:
conn = wvmInstance(
compute.hostname,
compute.login,
compute.password,
compute.type,
vname
compute.hostname, compute.login, compute.password, compute.type, vname
)
fqdn = get_hostname_by_ip(compute.hostname)

View file

@ -1,7 +1,6 @@
from instances.models import CreateInstance, Flavor, Instance, MigrateInstance
from rest_framework import serializers
from instances.models import Flavor, Instance, MigrateInstance, CreateInstance
class InstanceSerializer(serializers.ModelSerializer):
class Meta:

View file

@ -1,33 +1,31 @@
from django.shortcuts import get_object_or_404
from appsettings.settings import app_settings
from computes.models import Compute
from computes import utils
from computes.models import Compute
from django.shortcuts import get_object_or_404
from instances.models import Flavor, Instance
from instances.views import get_instance
from instances.utils import migrate_instance
from instances.views import destroy as instance_destroy
from instances.views import (
poweron,
force_off,
get_instance,
powercycle,
poweroff,
force_off,
suspend,
poweron,
resume,
destroy as instance_destroy,
suspend,
)
from rest_framework import status, viewsets, permissions
from rest_framework import permissions, status, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from vrtManager import util
from vrtManager.create import wvmCreate
from .serializers import (
FlavorSerializer,
InstanceSerializer,
InstanceDetailsSerializer,
MigrateSerializer,
CreateInstanceSerializer,
FlavorSerializer,
InstanceDetailsSerializer,
InstanceSerializer,
MigrateSerializer,
)
@ -40,14 +38,16 @@ class InstancesViewSet(viewsets.ViewSet):
def list(self, request):
if request.user.is_superuser or request.user.has_perm("instances.view_instances"):
if request.user.is_superuser or request.user.has_perm(
"instances.view_instances"
):
queryset = Instance.objects.all().prefetch_related("userinstance_set")
else:
queryset = Instance.objects.filter(userinstance__user=request.user).prefetch_related("userinstance_set")
queryset = Instance.objects.filter(
userinstance__user=request.user
).prefetch_related("userinstance_set")
serializer = InstanceSerializer(
queryset,
many=True,
context={"request": request}
queryset, many=True, context={"request": request}
)
return Response(serializer.data)
@ -72,11 +72,11 @@ class InstanceViewSet(viewsets.ViewSet):
utils.refresh_instance_database(compute)
queryset = Instance.objects.filter(compute=compute).prefetch_related("userinstance_set")
queryset = Instance.objects.filter(compute=compute).prefetch_related(
"userinstance_set"
)
serializer = InstanceSerializer(
queryset,
many=True,
context={"request": request}
queryset, many=True, context={"request": request}
)
return Response(serializer.data)
@ -190,7 +190,9 @@ class CreateInstanceViewSet(viewsets.ViewSet):
default_io = app_settings.INSTANCE_VOLUME_DEFAULT_IO
default_discard = app_settings.INSTANCE_VOLUME_DEFAULT_DISCARD
default_zeroes = app_settings.INSTANCE_VOLUME_DEFAULT_DETECT_ZEROES
default_scsi_disk_model = app_settings.INSTANCE_VOLUME_DEFAULT_SCSI_CONTROLLER
default_scsi_disk_model = (
app_settings.INSTANCE_VOLUME_DEFAULT_SCSI_CONTROLLER
)
default_disk_format = app_settings.INSTANCE_VOLUME_DEFAULT_FORMAT
default_disk_owner_uid = int(app_settings.INSTANCE_VOLUME_DEFAULT_OWNER_UID)
default_disk_owner_gid = int(app_settings.INSTANCE_VOLUME_DEFAULT_OWNER_GID)
@ -227,7 +229,9 @@ class CreateInstanceViewSet(viewsets.ViewSet):
volume_list.append(volume)
if "UEFI" in serializer.validated_data["firmware"]:
firmware["loader"] = (serializer.validated_data["firmware"].split(":")[1].strip())
firmware["loader"] = (
serializer.validated_data["firmware"].split(":")[1].strip()
)
firmware["secure"] = "no"
firmware["readonly"] = "yes"
firmware["type"] = "pflash"

View file

@ -1,9 +1,8 @@
import re
from appsettings.models import AppSettings
from django import forms
from django.utils.translation import gettext_lazy as _
from appsettings.models import AppSettings
from webvirtcloud.settings import QEMU_CONSOLE_LISTENER_ADDRESSES, QEMU_KEYMAPS
from .models import CreateInstance, Flavor

View file

@ -1,12 +1,10 @@
from computes.models import Compute
from django.db import models
from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _
from libvirt import VIR_DOMAIN_XML_SECURE
from webvirtcloud.settings import QEMU_CONSOLE_LISTENER_ADDRESSES
from computes.models import Compute
from vrtManager.instance import wvmInstance
from webvirtcloud.settings import QEMU_CONSOLE_LISTENER_ADDRESSES
class Flavor(models.Model):
@ -210,14 +208,10 @@ class Instance(models.Model):
class MigrateInstance(models.Model):
instance = models.ForeignKey(
Instance,
related_name="source_host",
on_delete=models.DO_NOTHING
Instance, related_name="source_host", on_delete=models.DO_NOTHING
)
target_compute = models.ForeignKey(
Compute,
related_name="target_host",
on_delete=models.DO_NOTHING
Compute, related_name="target_host", on_delete=models.DO_NOTHING
)
live = models.BooleanField(_("Live"))
@ -234,9 +228,7 @@ class MigrateInstance(models.Model):
class CreateInstance(models.Model):
compute = models.ForeignKey(
Compute,
related_name="host",
on_delete=models.DO_NOTHING
Compute, related_name="host", on_delete=models.DO_NOTHING
)
name = models.CharField(
max_length=64,

View file

@ -3,8 +3,8 @@ import json
import os
import re
import socket
import time
import subprocess
import time
from bisect import insort
from accounts.models import UserInstance, UserSSHKey
@ -20,12 +20,8 @@ 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 libvirt import (VIR_DOMAIN_UNDEFINE_KEEP_NVRAM, VIR_DOMAIN_UNDEFINE_NVRAM,
libvirtError)
from logs.views import addlogmsg
from vrtManager import util
from vrtManager.create import wvmCreate
@ -34,6 +30,8 @@ from vrtManager.interface import wvmInterface
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

View file

@ -6,89 +6,103 @@ from django.utils.translation import gettext_lazy as _
class AddInterface(forms.Form):
name = forms.CharField(max_length=10, required=True)
itype = forms.ChoiceField(required=True, choices=(('bridge', 'bridge'), ('ethernet', 'ethernet')))
itype = forms.ChoiceField(
required=True, choices=(("bridge", "bridge"), ("ethernet", "ethernet"))
)
start_mode = forms.ChoiceField(
required=True,
choices=(
('none', 'none'),
('onboot', 'onboot'),
('hotplug', 'hotplug')
)
choices=(("none", "none"), ("onboot", "onboot"), ("hotplug", "hotplug")),
)
netdev = forms.CharField(max_length=15, required=True)
ipv4_type = forms.ChoiceField(
required=True,
choices=(
('dhcp', 'dhcp'),
('static', 'static'),
('none', 'none')
)
choices=(("dhcp", "dhcp"), ("static", "static"), ("none", "none")),
)
ipv4_addr = forms.CharField(max_length=18, required=False)
ipv4_gw = forms.CharField(max_length=15, required=False)
ipv6_type = forms.ChoiceField(
required=True,
choices=(
('dhcp', 'dhcp'),
('static', 'static'),
('none', 'none')
)
choices=(("dhcp", "dhcp"), ("static", "static"), ("none", "none")),
)
ipv6_addr = forms.CharField(max_length=100, required=False)
ipv6_gw = forms.CharField(max_length=100, required=False)
stp = forms.ChoiceField(required=False, choices=(('on', 'on'), ('off', 'off')))
stp = forms.ChoiceField(required=False, choices=(("on", "on"), ("off", "off")))
delay = forms.IntegerField(required=False)
def clean_ipv4_addr(self):
ipv4_addr = self.cleaned_data['ipv4_addr']
have_symbol = re.match('^[0-9./]+$', ipv4_addr)
ipv4_addr = self.cleaned_data["ipv4_addr"]
have_symbol = re.match("^[0-9./]+$", ipv4_addr)
if not have_symbol:
raise forms.ValidationError(_('The IPv4 address must not contain any special characters'))
raise forms.ValidationError(
_("The IPv4 address must not contain any special characters")
)
elif len(ipv4_addr) > 20:
raise forms.ValidationError(_('The IPv4 address must not exceed 20 characters'))
raise forms.ValidationError(
_("The IPv4 address must not exceed 20 characters")
)
return ipv4_addr
def clean_ipv4_gw(self):
ipv4_gw = self.cleaned_data['ipv4_gw']
have_symbol = re.match('^[0-9.]+$', ipv4_gw)
ipv4_gw = self.cleaned_data["ipv4_gw"]
have_symbol = re.match("^[0-9.]+$", ipv4_gw)
if not have_symbol:
raise forms.ValidationError(_('The IPv4 gateway must not contain any special characters'))
raise forms.ValidationError(
_("The IPv4 gateway must not contain any special characters")
)
elif len(ipv4_gw) > 20:
raise forms.ValidationError(_('The IPv4 gateway must not exceed 20 characters'))
raise forms.ValidationError(
_("The IPv4 gateway must not exceed 20 characters")
)
return ipv4_gw
def clean_ipv6_addr(self):
ipv6_addr = self.cleaned_data['ipv6_addr']
have_symbol = re.match('^[0-9a-f./:]+|^$', ipv6_addr)
ipv6_addr = self.cleaned_data["ipv6_addr"]
have_symbol = re.match("^[0-9a-f./:]+|^$", ipv6_addr)
if not have_symbol:
raise forms.ValidationError(_('The IPv6 address must not contain any special characters'))
raise forms.ValidationError(
_("The IPv6 address must not contain any special characters")
)
elif len(ipv6_addr) > 100:
raise forms.ValidationError(_('The IPv6 address must not exceed 100 characters'))
raise forms.ValidationError(
_("The IPv6 address must not exceed 100 characters")
)
return ipv6_addr
def clean_ipv6_gw(self):
ipv6_gw = self.cleaned_data['ipv6_gw']
have_symbol = re.match('^[0-9a-f./:]+|^$', ipv6_gw)
ipv6_gw = self.cleaned_data["ipv6_gw"]
have_symbol = re.match("^[0-9a-f./:]+|^$", ipv6_gw)
if not have_symbol:
raise forms.ValidationError(_('The IPv6 gateway must not contain any special characters'))
raise forms.ValidationError(
_("The IPv6 gateway must not contain any special characters")
)
elif len(ipv6_gw) > 100:
raise forms.ValidationError(_('The IPv6 gateway must not exceed 100 characters'))
raise forms.ValidationError(
_("The IPv6 gateway must not exceed 100 characters")
)
return ipv6_gw
def clean_name(self):
name = self.cleaned_data['name']
have_symbol = re.match('^[a-z0-9.]+$', name)
name = self.cleaned_data["name"]
have_symbol = re.match("^[a-z0-9.]+$", name)
if not have_symbol:
raise forms.ValidationError(_('The interface must not contain any special characters'))
raise forms.ValidationError(
_("The interface must not contain any special characters")
)
elif len(name) > 10:
raise forms.ValidationError(_('The interface must not exceed 10 characters'))
raise forms.ValidationError(
_("The interface must not exceed 10 characters")
)
return name
def clean_netdev(self):
netdev = self.cleaned_data['netdev']
have_symbol = re.match('^[a-z0-9.:]+$', netdev)
netdev = self.cleaned_data["netdev"]
have_symbol = re.match("^[a-z0-9.:]+$", netdev)
if not have_symbol:
raise forms.ValidationError(_('The interface must not contain any special characters'))
raise forms.ValidationError(
_("The interface must not contain any special characters")
)
elif len(netdev) > 10:
raise forms.ValidationError(_('The interface must not exceed 10 characters'))
raise forms.ValidationError(
_("The interface must not exceed 10 characters")
)
return netdev

View file

@ -1,3 +1,4 @@
import contextlib
from django.contrib import messages
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect
@ -28,10 +29,10 @@ def interfaces(request, compute_id):
compute.type
)
ifaces = conn.get_ifaces()
try:
netdevs = conn.get_net_devices()
except:
netdevs = ["eth0", "eth1"]
with contextlib.suppress(Exception):
netdevs = conn.get_net_devices()
for iface in ifaces:
interf = wvmInterface(

View file

@ -1,5 +1,5 @@
from rest_framework import serializers
from networks.models import Networks
from rest_framework import serializers
class NetworksSerializer(serializers.ModelSerializer):

View file

@ -1,11 +1,10 @@
from django.shortcuts import get_object_or_404
from computes.models import Compute
from rest_framework import status, viewsets
from django.shortcuts import get_object_or_404
from rest_framework import viewsets
from rest_framework.response import Response
from vrtManager.network import wvmNetworks
from .serializers import NetworksSerializer
from rest_framework.response import Response
class NetworkViewSet(viewsets.ViewSet):
@ -17,10 +16,13 @@ class NetworkViewSet(viewsets.ViewSet):
compute = get_object_or_404(Compute, pk=compute_pk)
conn = wvmNetworks(compute.hostname, compute.login, compute.password, compute.type)
conn = wvmNetworks(
compute.hostname, compute.login, compute.password, compute.type
)
queryset = conn.get_networks_info()
serializer = NetworksSerializer(queryset, many=True, context={'request': request})
serializer = NetworksSerializer(
queryset, many=True, context={"request": request}
)
return Response(serializer.data)

View file

@ -1,15 +1,15 @@
from admin.decorators import superuser_only
from computes.models import Compute
from django.contrib import messages
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from libvirt import libvirtError
from admin.decorators import superuser_only
from computes.models import Compute
from networks.forms import AddNetPool
from vrtManager.network import network_size, wvmNetwork, wvmNetworks
from networks.forms import AddNetPool
@superuser_only
def networks(request, compute_id):

View file

@ -1,14 +1,12 @@
from django.shortcuts import get_object_or_404
from appsettings.settings import app_settings
from computes.models import Compute
from django.shortcuts import get_object_or_404
from rest_framework import status, viewsets
from rest_framework.decorators import action
from appsettings.settings import app_settings
from vrtManager.storage import wvmStorages, wvmStorage
from .serializers import StoragesSerializer, StorageSerializer, VolumeSerializer
from rest_framework.response import Response
from vrtManager.storage import wvmStorage, wvmStorages
from .serializers import StorageSerializer, StoragesSerializer, VolumeSerializer
class StorageViewSet(viewsets.ViewSet):
@ -20,17 +18,23 @@ class StorageViewSet(viewsets.ViewSet):
compute = get_object_or_404(Compute, pk=compute_pk)
conn = wvmStorages(compute.hostname, compute.login, compute.password, compute.type)
conn = wvmStorages(
compute.hostname, compute.login, compute.password, compute.type
)
queryset = conn.get_storages_info()
serializer = StoragesSerializer(queryset, many=True, context={'request': request})
serializer = StoragesSerializer(
queryset, many=True, context={"request": request}
)
return Response(serializer.data)
def retrieve(self, request, pk=None, compute_pk=None):
compute = get_object_or_404(Compute, pk=compute_pk)
conn = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, pk)
conn = wvmStorage(
compute.hostname, compute.login, compute.password, compute.type, pk
)
infoset = {
"state": conn.is_active(),
@ -40,48 +44,57 @@ class StorageViewSet(viewsets.ViewSet):
"path": conn.get_target_path(),
"type": conn.get_type(),
"autostart": conn.get_autostart(),
"volumes": conn.update_volumes()
"volumes": conn.update_volumes(),
}
serializer = StorageSerializer(infoset, many=False, context={'request': request})
serializer = StorageSerializer(
infoset, many=False, context={"request": request}
)
return Response(serializer.data)
@action(detail=True, methods=['post'])
@action(detail=True, methods=["post"])
def start(self, request, pk=None, compute_pk=None):
compute = get_object_or_404(Compute, pk=compute_pk)
conn = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, pk)
conn = wvmStorage(
compute.hostname, compute.login, compute.password, compute.type, pk
)
ret = conn.start()
conn.close()
return Response({'status': 'Pool start command send: ' + str(ret)})
return Response({"status": "Pool start command send: " + str(ret)})
@action(detail=True, methods=['post'])
@action(detail=True, methods=["post"])
def stop(self, request, pk=None, compute_pk=None):
compute = get_object_or_404(Compute, pk=compute_pk)
conn = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, pk)
conn = wvmStorage(
compute.hostname, compute.login, compute.password, compute.type, pk
)
ret = conn.stop()
conn.close()
return Response({'status': 'Pool stop command send: ' + str(ret)})
return Response({"status": "Pool stop command send: " + str(ret)})
@action(detail=True, methods=['post'])
@action(detail=True, methods=["post"])
def refresh(self, request, pk=None, compute_pk=None):
compute = get_object_or_404(Compute, pk=compute_pk)
conn = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, pk)
conn = wvmStorage(
compute.hostname, compute.login, compute.password, compute.type, pk
)
ret = conn.refresh()
conn.close()
return Response({'status': 'Pool refresh command send: ' + str(ret)})
return Response({"status": "Pool refresh command send: " + str(ret)})
@action(detail=True, methods=['post'])
@action(detail=True, methods=["post"])
def XML_description(self, request, pk=None, compute_pk=None):
compute = get_object_or_404(Compute, pk=compute_pk)
conn = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, pk)
conn = wvmStorage(
compute.hostname, compute.login, compute.password, compute.type, pk
)
ret = conn._XMLDesc(0)
conn.close()
return Response({'return': str(ret)})
return Response({"return": str(ret)})
class VolumeViewSet(viewsets.ViewSet):
@ -89,6 +102,7 @@ class VolumeViewSet(viewsets.ViewSet):
"""
A simple ViewSet for listing or retrieving Storage Volumes.
"""
serializer_class = VolumeSerializer
lookup_value_regex = "[^/]+"
@ -96,7 +110,9 @@ class VolumeViewSet(viewsets.ViewSet):
compute = get_object_or_404(Compute, pk=compute_pk)
conn = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, storage_pk)
conn = wvmStorage(
compute.hostname, compute.login, compute.password, compute.type, storage_pk
)
state = conn.is_active()
if state:
@ -105,14 +121,18 @@ class VolumeViewSet(viewsets.ViewSet):
else:
volume_queryset = None
conn.close()
serializer = VolumeSerializer(volume_queryset, many=True, context={'request': request})
serializer = VolumeSerializer(
volume_queryset, many=True, context={"request": request}
)
return Response(serializer.data)
def retrieve(self, request, storage_pk=None, compute_pk=None, pk=None):
compute = get_object_or_404(Compute, pk=compute_pk)
conn = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, storage_pk)
conn = wvmStorage(
compute.hostname, compute.login, compute.password, compute.type, storage_pk
)
state = conn.is_active()
if state:
@ -120,14 +140,18 @@ class VolumeViewSet(viewsets.ViewSet):
else:
volume_queryset = None
conn.close()
serializer = VolumeSerializer(volume_queryset, many=False, context={'request': request})
serializer = VolumeSerializer(
volume_queryset, many=False, context={"request": request}
)
return Response(serializer.data)
def create(self, request, storage_pk=None, compute_pk=None):
compute = get_object_or_404(Compute, pk=compute_pk)
conn = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, storage_pk)
conn = wvmStorage(
compute.hostname, compute.login, compute.password, compute.type, storage_pk
)
serializer = VolumeSerializer(data=request.data)
if serializer.is_valid():
@ -135,28 +159,30 @@ class VolumeViewSet(viewsets.ViewSet):
if state:
conn.refresh()
ret = conn.create_volume(
serializer.validated_data['name'],
serializer.validated_data['size'],
serializer.validated_data['type'],
serializer.validated_data['meta_prealloc'],
serializer.validated_data["name"],
serializer.validated_data["size"],
serializer.validated_data["type"],
serializer.validated_data["meta_prealloc"],
int(app_settings.INSTANCE_VOLUME_DEFAULT_OWNER_UID),
int(app_settings.INSTANCE_VOLUME_DEFAULT_OWNER_GID),
)
conn.close()
return Response({'status': 'Volume: ' + ret + ' is created'})
return Response({"status": "Volume: " + ret + " is created"})
else:
return Response({'status': 'Pool is not active'})
return Response({"status": "Pool is not active"})
else:
return Response({'status': 'Data is not right for create volume'})
return Response({"status": "Data is not right for create volume"})
def destroy(self, request, storage_pk=None, compute_pk=None, pk=None):
compute = get_object_or_404(Compute, pk=compute_pk)
conn = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, storage_pk)
conn = wvmStorage(
compute.hostname, compute.login, compute.password, compute.type, storage_pk
)
if conn.is_active():
conn.del_volume(pk)
conn.close()
return Response({'status': 'Volume: ' + pk + ' is deleted'})
return Response({"status": "Volume: " + pk + " is deleted"})
else:
return Response({'status': 'Pool is not active'})
return Response({"status": "Pool is not active"})

View file

@ -1,6 +1,7 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
# Create your models here.
class Storages(models.Model):
name = models.CharField(

View file

@ -1,19 +1,19 @@
import json
import os
from admin.decorators import superuser_only
from appsettings.settings import app_settings
from computes.models import Compute
from django.contrib import messages
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from libvirt import libvirtError
from admin.decorators import superuser_only
from appsettings.settings import app_settings
from computes.models import Compute
from storages.forms import AddStgPool, CloneImage, CreateVolumeForm
from vrtManager.storage import wvmStorage, wvmStorages
from storages.forms import AddStgPool, CloneImage, CreateVolumeForm
@superuser_only
def storages(request, compute_id):
@ -28,10 +28,7 @@ def storages(request, compute_id):
try:
conn = wvmStorages(
compute.hostname,
compute.login,
compute.password,
compute.type
compute.hostname, compute.login, compute.password, compute.type
)
storages = conn.get_storages_info()
secrets = conn.get_secrets()
@ -125,10 +122,7 @@ def storage(request, compute_id, pool):
form = CreateVolumeForm()
conn = wvmStorage(
compute.hostname,
compute.login,
compute.password,
compute.type, pool
compute.hostname, compute.login, compute.password, compute.type, pool
)
storages = conn.get_storages()
@ -234,11 +228,7 @@ def create_volume(request, compute_id, pool):
meta_prealloc = False
conn = wvmStorage(
compute.hostname,
compute.login,
compute.password,
compute.type,
pool
compute.hostname, compute.login, compute.password, compute.type, pool
)
storages = conn.get_storages()
@ -281,11 +271,7 @@ def get_volumes(request, compute_id, pool):
compute = get_object_or_404(Compute, pk=compute_id)
try:
conn = wvmStorage(
compute.hostname,
compute.login,
compute.password,
compute.type,
pool
compute.hostname, compute.login, compute.password, compute.type, pool
)
conn.refresh()
data["vols"] = sorted(conn.get_volumes())

View file

@ -1,5 +1,3 @@
from virtsecrets.forms import AddSecret
from admin.decorators import superuser_only
from computes.models import Compute
from django.contrib import messages
@ -15,6 +13,8 @@ from libvirt import (
)
from vrtManager.virtsecrets import wvmSecrets
from virtsecrets.forms import AddSecret
@superuser_only
def secrets(request, compute_id):
@ -36,10 +36,7 @@ def secrets(request, compute_id):
try:
conn = wvmSecrets(
compute.hostname,
compute.login,
compute.password,
compute.type
compute.hostname, compute.login, compute.password, compute.type
)
secrets = conn.get_secrets()

View file

@ -1,5 +1,5 @@
import string
import contextlib
import string
from vrtManager import util
from vrtManager.connection import wvmConnect

View file

@ -1,27 +1,26 @@
import contextlib
import json
import os.path
import time
try:
from libvirt import (
libvirtError,
VIR_DOMAIN_XML_SECURE,
VIR_DOMAIN_RUNNING,
VIR_DOMAIN_AFFECT_LIVE,
VIR_DOMAIN_AFFECT_CONFIG,
)
from libvirt import (
VIR_MIGRATE_LIVE,
VIR_MIGRATE_UNSAFE,
VIR_MIGRATE_PERSIST_DEST,
VIR_MIGRATE_UNDEFINE_SOURCE,
VIR_MIGRATE_OFFLINE,
VIR_MIGRATE_COMPRESSED,
VIR_DOMAIN_AFFECT_LIVE,
VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT,
VIR_DOMAIN_RUNNING,
VIR_DOMAIN_XML_SECURE,
VIR_MIGRATE_AUTO_CONVERGE,
VIR_MIGRATE_COMPRESSED,
VIR_MIGRATE_LIVE,
VIR_MIGRATE_OFFLINE,
VIR_MIGRATE_PERSIST_DEST,
VIR_MIGRATE_POSTCOPY,
VIR_MIGRATE_UNDEFINE_SOURCE,
VIR_MIGRATE_UNSAFE,
libvirtError,
)
from libvirt import VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT
from libvirt_qemu import qemuAgentCommand, VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT
from libvirt_qemu import VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT, qemuAgentCommand
except:
from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE, VIR_MIGRATE_LIVE
@ -496,26 +495,21 @@ class wvmInstance(wvmConnect):
s_name = disk.xpath("source/@pool")[0]
s = self.wvm.storagePoolLookupByName(s_name)
src_file = s.storageVolLookupByName(v).path()
try:
with contextlib.suppress(Exception):
disk_format = disk.xpath("driver/@type")[0]
except:
pass
try:
with contextlib.suppress(Exception):
disk_cache = disk.xpath("driver/@cache")[0]
except:
pass
try:
with contextlib.suppress(Exception):
disk_io = disk.xpath("driver/@io")[0]
except:
pass
try:
with contextlib.suppress(Exception):
disk_discard = disk.xpath("driver/@discard")[0]
except:
pass
try:
with contextlib.suppress(Exception):
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
@ -572,15 +566,14 @@ class wvmInstance(wvmConnect):
try:
dev = media.xpath("target/@dev")[0]
bus = media.xpath("target/@bus")[0]
try:
src_file = None
volume = src_file
with contextlib.suppress(Exception):
src_file = media.xpath("source/@file")[0]
vol = self.get_volume_by_path(src_file)
volume = vol.name()
stg = vol.storagePoolLookupByVolume()
storage = stg.name()
except:
src_file = None
volume = src_file
except:
pass
finally:
@ -1083,11 +1076,10 @@ class wvmInstance(wvmConnect):
graphic.set("listen", listener_addr)
listen.set("address", listener_addr)
else:
try:
with contextlib.suppress(Exception):
graphic.attrib.pop("listen")
listen.attrib.pop("address")
except:
pass
newxml = ElementTree.tostring(root).decode()
return self._defineXML(newxml)
@ -1158,10 +1150,9 @@ class wvmInstance(wvmConnect):
if passwd:
graphic.set("passwd", passwd)
else:
try:
with contextlib.suppress(Exception):
graphic.attrib.pop("passwd")
except:
pass
newxml = ElementTree.tostring(root).decode()
return self._defineXML(newxml)
@ -1177,10 +1168,9 @@ class wvmInstance(wvmConnect):
if keymap != "auto":
graphic.set("keymap", keymap)
else:
try:
with contextlib.suppress(Exception):
graphic.attrib.pop("keymap")
except:
pass
newxml = ElementTree.tostring(root).decode()
self._defineXML(newxml)
@ -1279,10 +1269,9 @@ class wvmInstance(wvmConnect):
for storage in storages:
stg = self.get_storage(storage)
if stg.info()[0] != 0:
try:
with contextlib.suppress(Exception):
stg.refresh(0)
except:
pass
for img in stg.listVolumes():
if img.lower().endswith(".iso"):
iso.append(img)
@ -1424,10 +1413,10 @@ class wvmInstance(wvmConnect):
device_name = elm.get("dev")
if device_name:
target_file = clone_data["disk-" + device_name]
try:
meta_prealloc = clone_data["meta-" + device_name]
except:
meta_prealloc = False
with contextlib.suppress(Exception):
meta_prealloc = clone_data["meta-" + device_name]
elm.set("dev", device_name)
elm = disk.find("source")
@ -1522,12 +1511,7 @@ class wvmInstance(wvmConnect):
return bridge_name
def add_network(
self,
mac_address,
source,
source_type="net",
model="virtio",
nwfilter=None
self, mac_address, source, source_type="net", model="virtio", nwfilter=None
):
if source_type == "net":
@ -1588,11 +1572,7 @@ class wvmInstance(wvmConnect):
status = self.delete_network(net_mac)
try:
self.add_network(
net_mac,
net_source,
net_source_type,
net_model,
net_filter
net_mac, net_source, net_source_type, net_model, net_filter
)
except libvirtError:
if status is not None:

View file

@ -1,17 +1,29 @@
from xml.etree import ElementTree
from libvirt import VIR_INTERFACE_XML_INACTIVE
from vrtManager import util
from vrtManager.connection import wvmConnect
class wvmInterfaces(wvmConnect):
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
self,
name,
itype,
mode,
netdev,
ipv4_type,
ipv4_addr,
ipv4_gw,
ipv6_type,
ipv6_addr,
ipv6_gw,
stp,
delay,
):
xml = f"""<interface type='{itype}' name='{name}'>
<start mode='{mode}'/>"""
@ -74,15 +86,21 @@ class wvmInterface(wvmConnect):
def get_ipv4_type(self):
try:
xml = self._XMLDesc(VIR_INTERFACE_XML_INACTIVE)
ipaddr = util.get_xml_path(xml, "/interface/protocol[@family='ipv4']/ip/@address")
ipaddr = util.get_xml_path(
xml, "/interface/protocol[@family='ipv4']/ip/@address"
)
return "static" if ipaddr else "dhcp"
except Exception:
return None
def get_ipv4(self):
xml = self._XMLDesc()
int_ipv4_ip = util.get_xml_path(xml, "/interface/protocol[@family='ipv4']/ip/@address")
int_ipv4_mask = util.get_xml_path(xml, "/interface/protocol[@family='ipv4']/ip/@prefix")
int_ipv4_ip = util.get_xml_path(
xml, "/interface/protocol[@family='ipv4']/ip/@address"
)
int_ipv4_mask = util.get_xml_path(
xml, "/interface/protocol[@family='ipv4']/ip/@prefix"
)
if not int_ipv4_ip or not int_ipv4_mask:
return None
else:
@ -91,15 +109,21 @@ class wvmInterface(wvmConnect):
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")
ipaddr = util.get_xml_path(
xml, "/interface/protocol[@family='ipv6']/ip/@address"
)
return "static" if ipaddr else "dhcp"
except Exception:
return None
def get_ipv6(self):
xml = self._XMLDesc()
int_ipv6_ip = util.get_xml_path(xml, "/interface/protocol[@family='ipv6']/ip/@address")
int_ipv6_mask = util.get_xml_path(xml, "/interface/protocol[@family='ipv6']/ip/@prefix")
int_ipv6_ip = util.get_xml_path(
xml, "/interface/protocol[@family='ipv6']/ip/@address"
)
int_ipv6_mask = util.get_xml_path(
xml, "/interface/protocol[@family='ipv6']/ip/@prefix"
)
if not int_ipv6_ip or not int_ipv6_mask:
return None
else:
@ -133,7 +157,15 @@ class wvmInterface(wvmConnect):
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})
ifaces.append(
{
"name": name,
"type": if_type,
"state": state,
"speed": speed,
"mac": address,
}
)
return ifaces
def get_details(self):

View file

@ -242,7 +242,7 @@ class wvmStorage(wvmConnect):
def refresh(self):
return self.pool.refresh(0)
def get_volume_details(self, volname):
def get_volumes_details(self):
with contextlib.suppress(Exception):
self.refresh()