mirror of
https://github.com/retspen/webvirtcloud
synced 2024-12-25 23:55:24 +00:00
commit
7db75784c6
27 changed files with 411 additions and 395 deletions
|
@ -30,9 +30,10 @@ def create_admin(sender, **kwargs):
|
||||||
"""
|
"""
|
||||||
Create initial admin user
|
Create initial admin user
|
||||||
"""
|
"""
|
||||||
from accounts.models import UserAttributes
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
from accounts.models import UserAttributes
|
||||||
|
|
||||||
plan = kwargs.get("plan", [])
|
plan = kwargs.get("plan", [])
|
||||||
for migration, rolled_back in plan:
|
for migration, rolled_back in plan:
|
||||||
if (
|
if (
|
||||||
|
|
|
@ -173,8 +173,7 @@ def email_otp(request):
|
||||||
send_email_with_otp(user, device)
|
send_email_with_otp(user, device)
|
||||||
|
|
||||||
messages.success(
|
messages.success(
|
||||||
request,
|
request, _("OTP Sent to %(email)s") % {"email": form.cleaned_data["email"]}
|
||||||
_("OTP Sent to %(email)s") % {"email": form.cleaned_data["email"]}
|
|
||||||
)
|
)
|
||||||
return redirect("accounts:login")
|
return redirect("accounts:login")
|
||||||
|
|
||||||
|
@ -195,12 +194,8 @@ def admin_email_otp(request, user_id):
|
||||||
if user.email != "":
|
if user.email != "":
|
||||||
send_email_with_otp(user, device)
|
send_email_with_otp(user, device)
|
||||||
messages.success(
|
messages.success(
|
||||||
request,
|
request, _("OTP QR code was emailed to user %(user)s") % {"user": user}
|
||||||
_("OTP QR code was emailed to user %(user)s") % {"user": user}
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
messages.error(
|
messages.error(request, _("User email not set, failed to send QR code"))
|
||||||
request,
|
|
||||||
_("User email not set, failed to send QR code")
|
|
||||||
)
|
|
||||||
return redirect("accounts:account", user.id)
|
return redirect("accounts:account", user.id)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from accounts.models import Instance, UserAttributes, UserInstance
|
||||||
|
from appsettings.settings import app_settings
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth import update_session_auth_hash
|
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.core.paginator import Paginator
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.utils.translation import gettext_lazy as _
|
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 logs.models import Logs
|
||||||
|
|
||||||
from . import forms
|
from . import forms
|
||||||
|
@ -149,8 +148,7 @@ def user_update_password(request, pk):
|
||||||
user = form.save()
|
user = form.save()
|
||||||
update_session_auth_hash(request, user) # Important!
|
update_session_auth_hash(request, user) # Important!
|
||||||
messages.success(
|
messages.success(
|
||||||
request,
|
request, _("Password changed for %(user)s") % {"user": user.username}
|
||||||
_("Password changed for %(user)s") % {"user": user.username}
|
|
||||||
)
|
)
|
||||||
return redirect("admin:user_list")
|
return redirect("admin:user_list")
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
from rest_framework import serializers
|
|
||||||
from computes.models import Compute
|
from computes.models import Compute
|
||||||
from vrtManager.connection import (
|
from rest_framework import serializers
|
||||||
CONN_SOCKET,
|
from vrtManager.connection import CONN_SOCKET, CONN_SSH, CONN_TCP, CONN_TLS
|
||||||
CONN_SSH,
|
|
||||||
CONN_TCP,
|
|
||||||
CONN_TLS,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class ComputeSerializer(serializers.ModelSerializer):
|
class ComputeSerializer(serializers.ModelSerializer):
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
from computes.models import Compute
|
from computes.models import Compute
|
||||||
from rest_framework import viewsets
|
from rest_framework import permissions, viewsets
|
||||||
from rest_framework import permissions
|
|
||||||
|
|
||||||
from vrtManager.create import wvmCreate
|
|
||||||
from .serializers import ComputeSerializer
|
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
from vrtManager.create import wvmCreate
|
||||||
|
|
||||||
|
from .serializers import ComputeSerializer
|
||||||
|
|
||||||
|
|
||||||
class ComputeViewSet(viewsets.ModelViewSet):
|
class ComputeViewSet(viewsets.ModelViewSet):
|
||||||
|
|
|
@ -12,4 +12,6 @@ def refresh_instance_database(compute):
|
||||||
names = Instance.objects.filter(compute=compute).values_list("name", flat=True)
|
names = Instance.objects.filter(compute=compute).values_list("name", flat=True)
|
||||||
for domain in domains:
|
for domain in domains:
|
||||||
if domain.name() not in names:
|
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()
|
||||||
|
|
|
@ -1,20 +1,12 @@
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
from admin.decorators import superuser_only
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils import timezone
|
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 instances.models import Instance
|
||||||
|
from libvirt import libvirtError
|
||||||
from vrtManager.connection import (
|
from vrtManager.connection import (
|
||||||
CONN_SOCKET,
|
CONN_SOCKET,
|
||||||
CONN_SSH,
|
CONN_SSH,
|
||||||
|
@ -25,6 +17,14 @@ from vrtManager.connection import (
|
||||||
)
|
)
|
||||||
from vrtManager.hostdetails import wvmHostDetails
|
from vrtManager.hostdetails import wvmHostDetails
|
||||||
|
|
||||||
|
from computes.forms import (
|
||||||
|
SocketComputeForm,
|
||||||
|
SshComputeForm,
|
||||||
|
TcpComputeForm,
|
||||||
|
TlsComputeForm,
|
||||||
|
)
|
||||||
|
from computes.models import Compute
|
||||||
|
|
||||||
from . import utils
|
from . import utils
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,7 +45,8 @@ def overview(request, compute_id):
|
||||||
compute = get_object_or_404(Compute, pk=compute_id)
|
compute = get_object_or_404(Compute, pk=compute_id)
|
||||||
status = (
|
status = (
|
||||||
"true"
|
"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(
|
conn = wvmHostDetails(
|
||||||
|
@ -82,9 +83,7 @@ def instances(request, compute_id):
|
||||||
)
|
)
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request, "computes/instances.html", {"compute": compute, "instances": instances}
|
||||||
"computes/instances.html",
|
|
||||||
{"compute": compute, "instances": instances}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -139,30 +138,9 @@ def compute_graph(request, compute_id):
|
||||||
:param compute_id:
|
:param compute_id:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
compute = get_object_or_404(Compute, pk=compute_id)
|
comp_mgr = ComputeManager(compute_id)
|
||||||
try:
|
data = comp_mgr.compute_graph()
|
||||||
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
|
|
||||||
|
|
||||||
data = json.dumps(
|
|
||||||
{
|
|
||||||
"cpudata": cpu_usage["usage"],
|
|
||||||
"memdata": mem_usage,
|
|
||||||
"timeline": current_time,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
response = HttpResponse()
|
response = HttpResponse()
|
||||||
response["Content-Type"] = "text/javascript"
|
response["Content-Type"] = "text/javascript"
|
||||||
response.write(data)
|
response.write(data)
|
||||||
|
@ -178,17 +156,87 @@ def get_compute_disk_buses(request, compute_id, arch, machine, disk):
|
||||||
:param disk:
|
:param disk:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
data = dict()
|
comp_mgr = ComputeManager(compute_id)
|
||||||
compute = get_object_or_404(Compute, pk=compute_id)
|
return HttpResponse(comp_mgr.get_disk_buses(arch, machine, disk))
|
||||||
try:
|
|
||||||
conn = wvmConnect(
|
|
||||||
compute.hostname,
|
def get_compute_machine_types(request, compute_id, arch):
|
||||||
compute.login,
|
"""
|
||||||
compute.password,
|
:param request:
|
||||||
compute.type,
|
: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 in disk_device_types:
|
||||||
if disk == "disk":
|
if disk == "disk":
|
||||||
|
@ -202,76 +250,29 @@ def get_compute_disk_buses(request, compute_id, arch, machine, disk):
|
||||||
except libvirtError:
|
except libvirtError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return HttpResponse(json.dumps(data))
|
return json.dumps(data)
|
||||||
|
|
||||||
|
def compute_graph(self):
|
||||||
def get_compute_machine_types(request, compute_id, arch):
|
|
||||||
"""
|
|
||||||
:param request:
|
|
||||||
:param compute_id:
|
|
||||||
:param arch:
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
data = dict()
|
|
||||||
try:
|
try:
|
||||||
compute = get_object_or_404(Compute, pk=compute_id)
|
conn = wvmHostDetails(
|
||||||
conn = wvmConnect(
|
self.compute.hostname,
|
||||||
compute.hostname,
|
self.compute.login,
|
||||||
compute.login,
|
self.compute.password,
|
||||||
compute.password,
|
self.compute.type,
|
||||||
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:
|
except libvirtError:
|
||||||
pass
|
cpu_usage = {"usage": 0}
|
||||||
|
mem_usage = {"usage": 0}
|
||||||
|
current_time = 0
|
||||||
|
|
||||||
return HttpResponse(json.dumps(data))
|
return json.dumps(
|
||||||
|
{
|
||||||
|
"cpudata": cpu_usage["usage"],
|
||||||
def get_compute_video_models(request, compute_id, arch, machine):
|
"memdata": mem_usage,
|
||||||
"""
|
"timeline": current_time,
|
||||||
: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_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))
|
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
import json
|
import json
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
from django.shortcuts import render, get_object_or_404
|
|
||||||
from django.http import HttpResponse, Http404
|
|
||||||
from libvirt import libvirtError
|
|
||||||
|
|
||||||
from accounts.models import UserInstance, UserSSHKey
|
from accounts.models import UserInstance, UserSSHKey
|
||||||
from computes.models import Compute
|
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
|
from vrtManager.instance import wvmInstance
|
||||||
|
|
||||||
|
|
||||||
OS_VERSIONS = ["latest", ""]
|
OS_VERSIONS = ["latest", ""]
|
||||||
OS_UUID = "iid-dswebvirtcloud"
|
OS_UUID = "iid-dswebvirtcloud"
|
||||||
|
|
||||||
|
@ -100,11 +98,7 @@ def get_vdi_url(request, compute_id, vname):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
conn = wvmInstance(
|
conn = wvmInstance(
|
||||||
compute.hostname,
|
compute.hostname, compute.login, compute.password, compute.type, vname
|
||||||
compute.login,
|
|
||||||
compute.password,
|
|
||||||
compute.type,
|
|
||||||
vname
|
|
||||||
)
|
)
|
||||||
|
|
||||||
fqdn = get_hostname_by_ip(compute.hostname)
|
fqdn = get_hostname_by_ip(compute.hostname)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
|
from instances.models import CreateInstance, Flavor, Instance, MigrateInstance
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from instances.models import Flavor, Instance, MigrateInstance, CreateInstance
|
|
||||||
|
|
||||||
|
|
||||||
class InstanceSerializer(serializers.ModelSerializer):
|
class InstanceSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
@ -1,33 +1,31 @@
|
||||||
from django.shortcuts import get_object_or_404
|
|
||||||
from appsettings.settings import app_settings
|
from appsettings.settings import app_settings
|
||||||
from computes.models import Compute
|
|
||||||
from computes import utils
|
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.models import Flavor, Instance
|
||||||
from instances.views import get_instance
|
|
||||||
from instances.utils import migrate_instance
|
from instances.utils import migrate_instance
|
||||||
|
from instances.views import destroy as instance_destroy
|
||||||
from instances.views import (
|
from instances.views import (
|
||||||
poweron,
|
force_off,
|
||||||
|
get_instance,
|
||||||
powercycle,
|
powercycle,
|
||||||
poweroff,
|
poweroff,
|
||||||
force_off,
|
poweron,
|
||||||
suspend,
|
|
||||||
resume,
|
resume,
|
||||||
destroy as instance_destroy,
|
suspend,
|
||||||
)
|
)
|
||||||
|
from rest_framework import permissions, status, viewsets
|
||||||
from rest_framework import status, viewsets, permissions
|
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
||||||
from vrtManager import util
|
from vrtManager import util
|
||||||
|
|
||||||
from vrtManager.create import wvmCreate
|
from vrtManager.create import wvmCreate
|
||||||
|
|
||||||
from .serializers import (
|
from .serializers import (
|
||||||
FlavorSerializer,
|
|
||||||
InstanceSerializer,
|
|
||||||
InstanceDetailsSerializer,
|
|
||||||
MigrateSerializer,
|
|
||||||
CreateInstanceSerializer,
|
CreateInstanceSerializer,
|
||||||
|
FlavorSerializer,
|
||||||
|
InstanceDetailsSerializer,
|
||||||
|
InstanceSerializer,
|
||||||
|
MigrateSerializer,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,14 +38,16 @@ class InstancesViewSet(viewsets.ViewSet):
|
||||||
|
|
||||||
def list(self, request):
|
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")
|
queryset = Instance.objects.all().prefetch_related("userinstance_set")
|
||||||
else:
|
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(
|
serializer = InstanceSerializer(
|
||||||
queryset,
|
queryset, many=True, context={"request": request}
|
||||||
many=True,
|
|
||||||
context={"request": request}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return Response(serializer.data)
|
return Response(serializer.data)
|
||||||
|
@ -72,11 +72,11 @@ class InstanceViewSet(viewsets.ViewSet):
|
||||||
|
|
||||||
utils.refresh_instance_database(compute)
|
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(
|
serializer = InstanceSerializer(
|
||||||
queryset,
|
queryset, many=True, context={"request": request}
|
||||||
many=True,
|
|
||||||
context={"request": request}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return Response(serializer.data)
|
return Response(serializer.data)
|
||||||
|
@ -190,7 +190,9 @@ class CreateInstanceViewSet(viewsets.ViewSet):
|
||||||
default_io = app_settings.INSTANCE_VOLUME_DEFAULT_IO
|
default_io = app_settings.INSTANCE_VOLUME_DEFAULT_IO
|
||||||
default_discard = app_settings.INSTANCE_VOLUME_DEFAULT_DISCARD
|
default_discard = app_settings.INSTANCE_VOLUME_DEFAULT_DISCARD
|
||||||
default_zeroes = app_settings.INSTANCE_VOLUME_DEFAULT_DETECT_ZEROES
|
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_format = app_settings.INSTANCE_VOLUME_DEFAULT_FORMAT
|
||||||
default_disk_owner_uid = int(app_settings.INSTANCE_VOLUME_DEFAULT_OWNER_UID)
|
default_disk_owner_uid = int(app_settings.INSTANCE_VOLUME_DEFAULT_OWNER_UID)
|
||||||
default_disk_owner_gid = int(app_settings.INSTANCE_VOLUME_DEFAULT_OWNER_GID)
|
default_disk_owner_gid = int(app_settings.INSTANCE_VOLUME_DEFAULT_OWNER_GID)
|
||||||
|
@ -227,7 +229,9 @@ class CreateInstanceViewSet(viewsets.ViewSet):
|
||||||
volume_list.append(volume)
|
volume_list.append(volume)
|
||||||
|
|
||||||
if "UEFI" in serializer.validated_data["firmware"]:
|
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["secure"] = "no"
|
||||||
firmware["readonly"] = "yes"
|
firmware["readonly"] = "yes"
|
||||||
firmware["type"] = "pflash"
|
firmware["type"] = "pflash"
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from appsettings.models import AppSettings
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from appsettings.models import AppSettings
|
|
||||||
from webvirtcloud.settings import QEMU_CONSOLE_LISTENER_ADDRESSES, QEMU_KEYMAPS
|
from webvirtcloud.settings import QEMU_CONSOLE_LISTENER_ADDRESSES, QEMU_KEYMAPS
|
||||||
|
|
||||||
from .models import CreateInstance, Flavor
|
from .models import CreateInstance, Flavor
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
|
from computes.models import Compute
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from libvirt import VIR_DOMAIN_XML_SECURE
|
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 vrtManager.instance import wvmInstance
|
||||||
|
from webvirtcloud.settings import QEMU_CONSOLE_LISTENER_ADDRESSES
|
||||||
|
|
||||||
|
|
||||||
class Flavor(models.Model):
|
class Flavor(models.Model):
|
||||||
|
@ -210,14 +208,10 @@ class Instance(models.Model):
|
||||||
|
|
||||||
class MigrateInstance(models.Model):
|
class MigrateInstance(models.Model):
|
||||||
instance = models.ForeignKey(
|
instance = models.ForeignKey(
|
||||||
Instance,
|
Instance, related_name="source_host", on_delete=models.DO_NOTHING
|
||||||
related_name="source_host",
|
|
||||||
on_delete=models.DO_NOTHING
|
|
||||||
)
|
)
|
||||||
target_compute = models.ForeignKey(
|
target_compute = models.ForeignKey(
|
||||||
Compute,
|
Compute, related_name="target_host", on_delete=models.DO_NOTHING
|
||||||
related_name="target_host",
|
|
||||||
on_delete=models.DO_NOTHING
|
|
||||||
)
|
)
|
||||||
|
|
||||||
live = models.BooleanField(_("Live"))
|
live = models.BooleanField(_("Live"))
|
||||||
|
@ -234,9 +228,7 @@ class MigrateInstance(models.Model):
|
||||||
|
|
||||||
class CreateInstance(models.Model):
|
class CreateInstance(models.Model):
|
||||||
compute = models.ForeignKey(
|
compute = models.ForeignKey(
|
||||||
Compute,
|
Compute, related_name="host", on_delete=models.DO_NOTHING
|
||||||
related_name="host",
|
|
||||||
on_delete=models.DO_NOTHING
|
|
||||||
)
|
)
|
||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
max_length=64,
|
max_length=64,
|
||||||
|
|
|
@ -3,8 +3,8 @@ import json
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
import time
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import time
|
||||||
from bisect import insort
|
from bisect import insort
|
||||||
|
|
||||||
from accounts.models import UserInstance, UserSSHKey
|
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.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.translation import gettext_lazy as _
|
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,
|
||||||
from libvirt import (
|
libvirtError)
|
||||||
VIR_DOMAIN_UNDEFINE_KEEP_NVRAM,
|
|
||||||
VIR_DOMAIN_UNDEFINE_NVRAM,
|
|
||||||
libvirtError,
|
|
||||||
)
|
|
||||||
from logs.views import addlogmsg
|
from logs.views import addlogmsg
|
||||||
from vrtManager import util
|
from vrtManager import util
|
||||||
from vrtManager.create import wvmCreate
|
from vrtManager.create import wvmCreate
|
||||||
|
@ -34,6 +30,8 @@ from vrtManager.interface import wvmInterface
|
||||||
from vrtManager.storage import wvmStorage
|
from vrtManager.storage import wvmStorage
|
||||||
from vrtManager.util import randomPasswd
|
from vrtManager.util import randomPasswd
|
||||||
|
|
||||||
|
from instances.models import Instance
|
||||||
|
|
||||||
from . import utils
|
from . import utils
|
||||||
from .forms import ConsoleForm, FlavorForm, NewVMForm
|
from .forms import ConsoleForm, FlavorForm, NewVMForm
|
||||||
from .models import Flavor
|
from .models import Flavor
|
||||||
|
|
|
@ -6,89 +6,103 @@ from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
class AddInterface(forms.Form):
|
class AddInterface(forms.Form):
|
||||||
name = forms.CharField(max_length=10, required=True)
|
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(
|
start_mode = forms.ChoiceField(
|
||||||
required=True,
|
required=True,
|
||||||
choices=(
|
choices=(("none", "none"), ("onboot", "onboot"), ("hotplug", "hotplug")),
|
||||||
('none', 'none'),
|
|
||||||
('onboot', 'onboot'),
|
|
||||||
('hotplug', 'hotplug')
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
netdev = forms.CharField(max_length=15, required=True)
|
netdev = forms.CharField(max_length=15, required=True)
|
||||||
ipv4_type = forms.ChoiceField(
|
ipv4_type = forms.ChoiceField(
|
||||||
required=True,
|
required=True,
|
||||||
choices=(
|
choices=(("dhcp", "dhcp"), ("static", "static"), ("none", "none")),
|
||||||
('dhcp', 'dhcp'),
|
|
||||||
('static', 'static'),
|
|
||||||
('none', 'none')
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
ipv4_addr = forms.CharField(max_length=18, required=False)
|
ipv4_addr = forms.CharField(max_length=18, required=False)
|
||||||
ipv4_gw = forms.CharField(max_length=15, required=False)
|
ipv4_gw = forms.CharField(max_length=15, required=False)
|
||||||
ipv6_type = forms.ChoiceField(
|
ipv6_type = forms.ChoiceField(
|
||||||
required=True,
|
required=True,
|
||||||
choices=(
|
choices=(("dhcp", "dhcp"), ("static", "static"), ("none", "none")),
|
||||||
('dhcp', 'dhcp'),
|
|
||||||
('static', 'static'),
|
|
||||||
('none', 'none')
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
ipv6_addr = forms.CharField(max_length=100, required=False)
|
ipv6_addr = forms.CharField(max_length=100, required=False)
|
||||||
ipv6_gw = 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)
|
delay = forms.IntegerField(required=False)
|
||||||
|
|
||||||
def clean_ipv4_addr(self):
|
def clean_ipv4_addr(self):
|
||||||
ipv4_addr = self.cleaned_data['ipv4_addr']
|
ipv4_addr = self.cleaned_data["ipv4_addr"]
|
||||||
have_symbol = re.match('^[0-9./]+$', ipv4_addr)
|
have_symbol = re.match("^[0-9./]+$", ipv4_addr)
|
||||||
if not have_symbol:
|
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:
|
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
|
return ipv4_addr
|
||||||
|
|
||||||
def clean_ipv4_gw(self):
|
def clean_ipv4_gw(self):
|
||||||
ipv4_gw = self.cleaned_data['ipv4_gw']
|
ipv4_gw = self.cleaned_data["ipv4_gw"]
|
||||||
have_symbol = re.match('^[0-9.]+$', ipv4_gw)
|
have_symbol = re.match("^[0-9.]+$", ipv4_gw)
|
||||||
if not have_symbol:
|
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:
|
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
|
return ipv4_gw
|
||||||
|
|
||||||
def clean_ipv6_addr(self):
|
def clean_ipv6_addr(self):
|
||||||
ipv6_addr = self.cleaned_data['ipv6_addr']
|
ipv6_addr = self.cleaned_data["ipv6_addr"]
|
||||||
have_symbol = re.match('^[0-9a-f./:]+|^$', ipv6_addr)
|
have_symbol = re.match("^[0-9a-f./:]+|^$", ipv6_addr)
|
||||||
if not have_symbol:
|
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:
|
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
|
return ipv6_addr
|
||||||
|
|
||||||
def clean_ipv6_gw(self):
|
def clean_ipv6_gw(self):
|
||||||
ipv6_gw = self.cleaned_data['ipv6_gw']
|
ipv6_gw = self.cleaned_data["ipv6_gw"]
|
||||||
have_symbol = re.match('^[0-9a-f./:]+|^$', ipv6_gw)
|
have_symbol = re.match("^[0-9a-f./:]+|^$", ipv6_gw)
|
||||||
if not have_symbol:
|
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:
|
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
|
return ipv6_gw
|
||||||
|
|
||||||
def clean_name(self):
|
def clean_name(self):
|
||||||
name = self.cleaned_data['name']
|
name = self.cleaned_data["name"]
|
||||||
have_symbol = re.match('^[a-z0-9.]+$', name)
|
have_symbol = re.match("^[a-z0-9.]+$", name)
|
||||||
if not have_symbol:
|
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:
|
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
|
return name
|
||||||
|
|
||||||
def clean_netdev(self):
|
def clean_netdev(self):
|
||||||
netdev = self.cleaned_data['netdev']
|
netdev = self.cleaned_data["netdev"]
|
||||||
have_symbol = re.match('^[a-z0-9.:]+$', netdev)
|
have_symbol = re.match("^[a-z0-9.:]+$", netdev)
|
||||||
if not have_symbol:
|
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:
|
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
|
return netdev
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import contextlib
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.shortcuts import render, get_object_or_404
|
from django.shortcuts import render, get_object_or_404
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
|
@ -28,10 +29,10 @@ def interfaces(request, compute_id):
|
||||||
compute.type
|
compute.type
|
||||||
)
|
)
|
||||||
ifaces = conn.get_ifaces()
|
ifaces = conn.get_ifaces()
|
||||||
try:
|
|
||||||
netdevs = conn.get_net_devices()
|
|
||||||
except:
|
|
||||||
netdevs = ["eth0", "eth1"]
|
netdevs = ["eth0", "eth1"]
|
||||||
|
with contextlib.suppress(Exception):
|
||||||
|
netdevs = conn.get_net_devices()
|
||||||
|
|
||||||
for iface in ifaces:
|
for iface in ifaces:
|
||||||
interf = wvmInterface(
|
interf = wvmInterface(
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from rest_framework import serializers
|
|
||||||
from networks.models import Networks
|
from networks.models import Networks
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
|
||||||
class NetworksSerializer(serializers.ModelSerializer):
|
class NetworksSerializer(serializers.ModelSerializer):
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
from django.shortcuts import get_object_or_404
|
|
||||||
from computes.models import Compute
|
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 vrtManager.network import wvmNetworks
|
||||||
|
|
||||||
from .serializers import NetworksSerializer
|
from .serializers import NetworksSerializer
|
||||||
from rest_framework.response import Response
|
|
||||||
|
|
||||||
|
|
||||||
class NetworkViewSet(viewsets.ViewSet):
|
class NetworkViewSet(viewsets.ViewSet):
|
||||||
|
@ -17,10 +16,13 @@ class NetworkViewSet(viewsets.ViewSet):
|
||||||
|
|
||||||
compute = get_object_or_404(Compute, pk=compute_pk)
|
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()
|
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)
|
return Response(serializer.data)
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
|
from admin.decorators import superuser_only
|
||||||
|
from computes.models import Compute
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.shortcuts import get_object_or_404, render
|
from django.shortcuts import get_object_or_404, render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from libvirt import libvirtError
|
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 vrtManager.network import network_size, wvmNetwork, wvmNetworks
|
||||||
|
|
||||||
|
from networks.forms import AddNetPool
|
||||||
|
|
||||||
|
|
||||||
@superuser_only
|
@superuser_only
|
||||||
def networks(request, compute_id):
|
def networks(request, compute_id):
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
from django.shortcuts import get_object_or_404
|
from appsettings.settings import app_settings
|
||||||
from computes.models import Compute
|
from computes.models import Compute
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
from rest_framework import status, viewsets
|
from rest_framework import status, viewsets
|
||||||
from rest_framework.decorators import action
|
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 rest_framework.response import Response
|
||||||
|
from vrtManager.storage import wvmStorage, wvmStorages
|
||||||
|
|
||||||
|
from .serializers import StorageSerializer, StoragesSerializer, VolumeSerializer
|
||||||
|
|
||||||
|
|
||||||
class StorageViewSet(viewsets.ViewSet):
|
class StorageViewSet(viewsets.ViewSet):
|
||||||
|
@ -20,17 +18,23 @@ class StorageViewSet(viewsets.ViewSet):
|
||||||
|
|
||||||
compute = get_object_or_404(Compute, pk=compute_pk)
|
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()
|
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)
|
return Response(serializer.data)
|
||||||
|
|
||||||
def retrieve(self, request, pk=None, compute_pk=None):
|
def retrieve(self, request, pk=None, compute_pk=None):
|
||||||
compute = get_object_or_404(Compute, pk=compute_pk)
|
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 = {
|
infoset = {
|
||||||
"state": conn.is_active(),
|
"state": conn.is_active(),
|
||||||
|
@ -40,48 +44,57 @@ class StorageViewSet(viewsets.ViewSet):
|
||||||
"path": conn.get_target_path(),
|
"path": conn.get_target_path(),
|
||||||
"type": conn.get_type(),
|
"type": conn.get_type(),
|
||||||
"autostart": conn.get_autostart(),
|
"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)
|
return Response(serializer.data)
|
||||||
|
|
||||||
|
@action(detail=True, methods=["post"])
|
||||||
@action(detail=True, methods=['post'])
|
|
||||||
def start(self, request, pk=None, compute_pk=None):
|
def start(self, request, pk=None, compute_pk=None):
|
||||||
compute = get_object_or_404(Compute, pk=compute_pk)
|
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()
|
ret = conn.start()
|
||||||
conn.close()
|
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):
|
def stop(self, request, pk=None, compute_pk=None):
|
||||||
compute = get_object_or_404(Compute, pk=compute_pk)
|
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()
|
ret = conn.stop()
|
||||||
conn.close()
|
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):
|
def refresh(self, request, pk=None, compute_pk=None):
|
||||||
compute = get_object_or_404(Compute, pk=compute_pk)
|
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()
|
ret = conn.refresh()
|
||||||
conn.close()
|
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):
|
def XML_description(self, request, pk=None, compute_pk=None):
|
||||||
compute = get_object_or_404(Compute, pk=compute_pk)
|
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)
|
ret = conn._XMLDesc(0)
|
||||||
conn.close()
|
conn.close()
|
||||||
return Response({'return': str(ret)})
|
return Response({"return": str(ret)})
|
||||||
|
|
||||||
|
|
||||||
class VolumeViewSet(viewsets.ViewSet):
|
class VolumeViewSet(viewsets.ViewSet):
|
||||||
|
@ -89,6 +102,7 @@ class VolumeViewSet(viewsets.ViewSet):
|
||||||
"""
|
"""
|
||||||
A simple ViewSet for listing or retrieving Storage Volumes.
|
A simple ViewSet for listing or retrieving Storage Volumes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
serializer_class = VolumeSerializer
|
serializer_class = VolumeSerializer
|
||||||
lookup_value_regex = "[^/]+"
|
lookup_value_regex = "[^/]+"
|
||||||
|
|
||||||
|
@ -96,7 +110,9 @@ class VolumeViewSet(viewsets.ViewSet):
|
||||||
|
|
||||||
compute = get_object_or_404(Compute, pk=compute_pk)
|
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()
|
state = conn.is_active()
|
||||||
|
|
||||||
if state:
|
if state:
|
||||||
|
@ -105,14 +121,18 @@ class VolumeViewSet(viewsets.ViewSet):
|
||||||
else:
|
else:
|
||||||
volume_queryset = None
|
volume_queryset = None
|
||||||
conn.close()
|
conn.close()
|
||||||
serializer = VolumeSerializer(volume_queryset, many=True, context={'request': request})
|
serializer = VolumeSerializer(
|
||||||
|
volume_queryset, many=True, context={"request": request}
|
||||||
|
)
|
||||||
|
|
||||||
return Response(serializer.data)
|
return Response(serializer.data)
|
||||||
|
|
||||||
def retrieve(self, request, storage_pk=None, compute_pk=None, pk=None):
|
def retrieve(self, request, storage_pk=None, compute_pk=None, pk=None):
|
||||||
compute = get_object_or_404(Compute, pk=compute_pk)
|
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()
|
state = conn.is_active()
|
||||||
|
|
||||||
if state:
|
if state:
|
||||||
|
@ -120,14 +140,18 @@ class VolumeViewSet(viewsets.ViewSet):
|
||||||
else:
|
else:
|
||||||
volume_queryset = None
|
volume_queryset = None
|
||||||
conn.close()
|
conn.close()
|
||||||
serializer = VolumeSerializer(volume_queryset, many=False, context={'request': request})
|
serializer = VolumeSerializer(
|
||||||
|
volume_queryset, many=False, context={"request": request}
|
||||||
|
)
|
||||||
|
|
||||||
return Response(serializer.data)
|
return Response(serializer.data)
|
||||||
|
|
||||||
def create(self, request, storage_pk=None, compute_pk=None):
|
def create(self, request, storage_pk=None, compute_pk=None):
|
||||||
compute = get_object_or_404(Compute, pk=compute_pk)
|
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)
|
serializer = VolumeSerializer(data=request.data)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
|
@ -135,28 +159,30 @@ class VolumeViewSet(viewsets.ViewSet):
|
||||||
if state:
|
if state:
|
||||||
conn.refresh()
|
conn.refresh()
|
||||||
ret = conn.create_volume(
|
ret = conn.create_volume(
|
||||||
serializer.validated_data['name'],
|
serializer.validated_data["name"],
|
||||||
serializer.validated_data['size'],
|
serializer.validated_data["size"],
|
||||||
serializer.validated_data['type'],
|
serializer.validated_data["type"],
|
||||||
serializer.validated_data['meta_prealloc'],
|
serializer.validated_data["meta_prealloc"],
|
||||||
int(app_settings.INSTANCE_VOLUME_DEFAULT_OWNER_UID),
|
int(app_settings.INSTANCE_VOLUME_DEFAULT_OWNER_UID),
|
||||||
int(app_settings.INSTANCE_VOLUME_DEFAULT_OWNER_GID),
|
int(app_settings.INSTANCE_VOLUME_DEFAULT_OWNER_GID),
|
||||||
)
|
)
|
||||||
conn.close()
|
conn.close()
|
||||||
return Response({'status': 'Volume: ' + ret + ' is created'})
|
return Response({"status": "Volume: " + ret + " is created"})
|
||||||
else:
|
else:
|
||||||
return Response({'status': 'Pool is not active'})
|
return Response({"status": "Pool is not active"})
|
||||||
else:
|
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):
|
def destroy(self, request, storage_pk=None, compute_pk=None, pk=None):
|
||||||
compute = get_object_or_404(Compute, pk=compute_pk)
|
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():
|
if conn.is_active():
|
||||||
conn.del_volume(pk)
|
conn.del_volume(pk)
|
||||||
conn.close()
|
conn.close()
|
||||||
return Response({'status': 'Volume: ' + pk + ' is deleted'})
|
return Response({"status": "Volume: " + pk + " is deleted"})
|
||||||
else:
|
else:
|
||||||
return Response({'status': 'Pool is not active'})
|
return Response({"status": "Pool is not active"})
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
class Storages(models.Model):
|
class Storages(models.Model):
|
||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
import json
|
import json
|
||||||
import os
|
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.contrib import messages
|
||||||
from django.http import HttpResponse, HttpResponseRedirect
|
from django.http import HttpResponse, HttpResponseRedirect
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from libvirt import libvirtError
|
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 vrtManager.storage import wvmStorage, wvmStorages
|
||||||
|
|
||||||
|
from storages.forms import AddStgPool, CloneImage, CreateVolumeForm
|
||||||
|
|
||||||
|
|
||||||
@superuser_only
|
@superuser_only
|
||||||
def storages(request, compute_id):
|
def storages(request, compute_id):
|
||||||
|
@ -28,10 +28,7 @@ def storages(request, compute_id):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
conn = wvmStorages(
|
conn = wvmStorages(
|
||||||
compute.hostname,
|
compute.hostname, compute.login, compute.password, compute.type
|
||||||
compute.login,
|
|
||||||
compute.password,
|
|
||||||
compute.type
|
|
||||||
)
|
)
|
||||||
storages = conn.get_storages_info()
|
storages = conn.get_storages_info()
|
||||||
secrets = conn.get_secrets()
|
secrets = conn.get_secrets()
|
||||||
|
@ -125,10 +122,7 @@ def storage(request, compute_id, pool):
|
||||||
form = CreateVolumeForm()
|
form = CreateVolumeForm()
|
||||||
|
|
||||||
conn = wvmStorage(
|
conn = wvmStorage(
|
||||||
compute.hostname,
|
compute.hostname, compute.login, compute.password, compute.type, pool
|
||||||
compute.login,
|
|
||||||
compute.password,
|
|
||||||
compute.type, pool
|
|
||||||
)
|
)
|
||||||
|
|
||||||
storages = conn.get_storages()
|
storages = conn.get_storages()
|
||||||
|
@ -234,11 +228,7 @@ def create_volume(request, compute_id, pool):
|
||||||
meta_prealloc = False
|
meta_prealloc = False
|
||||||
|
|
||||||
conn = wvmStorage(
|
conn = wvmStorage(
|
||||||
compute.hostname,
|
compute.hostname, compute.login, compute.password, compute.type, pool
|
||||||
compute.login,
|
|
||||||
compute.password,
|
|
||||||
compute.type,
|
|
||||||
pool
|
|
||||||
)
|
)
|
||||||
|
|
||||||
storages = conn.get_storages()
|
storages = conn.get_storages()
|
||||||
|
@ -281,11 +271,7 @@ def get_volumes(request, compute_id, pool):
|
||||||
compute = get_object_or_404(Compute, pk=compute_id)
|
compute = get_object_or_404(Compute, pk=compute_id)
|
||||||
try:
|
try:
|
||||||
conn = wvmStorage(
|
conn = wvmStorage(
|
||||||
compute.hostname,
|
compute.hostname, compute.login, compute.password, compute.type, pool
|
||||||
compute.login,
|
|
||||||
compute.password,
|
|
||||||
compute.type,
|
|
||||||
pool
|
|
||||||
)
|
)
|
||||||
conn.refresh()
|
conn.refresh()
|
||||||
data["vols"] = sorted(conn.get_volumes())
|
data["vols"] = sorted(conn.get_volumes())
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
from virtsecrets.forms import AddSecret
|
|
||||||
|
|
||||||
from admin.decorators import superuser_only
|
from admin.decorators import superuser_only
|
||||||
from computes.models import Compute
|
from computes.models import Compute
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
|
@ -15,6 +13,8 @@ from libvirt import (
|
||||||
)
|
)
|
||||||
from vrtManager.virtsecrets import wvmSecrets
|
from vrtManager.virtsecrets import wvmSecrets
|
||||||
|
|
||||||
|
from virtsecrets.forms import AddSecret
|
||||||
|
|
||||||
|
|
||||||
@superuser_only
|
@superuser_only
|
||||||
def secrets(request, compute_id):
|
def secrets(request, compute_id):
|
||||||
|
@ -36,10 +36,7 @@ def secrets(request, compute_id):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
conn = wvmSecrets(
|
conn = wvmSecrets(
|
||||||
compute.hostname,
|
compute.hostname, compute.login, compute.password, compute.type
|
||||||
compute.login,
|
|
||||||
compute.password,
|
|
||||||
compute.type
|
|
||||||
)
|
)
|
||||||
secrets = conn.get_secrets()
|
secrets = conn.get_secrets()
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import string
|
|
||||||
import contextlib
|
import contextlib
|
||||||
|
import string
|
||||||
|
|
||||||
from vrtManager import util
|
from vrtManager import util
|
||||||
from vrtManager.connection import wvmConnect
|
from vrtManager.connection import wvmConnect
|
||||||
|
|
|
@ -1,27 +1,26 @@
|
||||||
|
import contextlib
|
||||||
import json
|
import json
|
||||||
import os.path
|
import os.path
|
||||||
import time
|
import time
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from libvirt import (
|
from libvirt import (
|
||||||
libvirtError,
|
|
||||||
VIR_DOMAIN_XML_SECURE,
|
|
||||||
VIR_DOMAIN_RUNNING,
|
|
||||||
VIR_DOMAIN_AFFECT_LIVE,
|
|
||||||
VIR_DOMAIN_AFFECT_CONFIG,
|
VIR_DOMAIN_AFFECT_CONFIG,
|
||||||
)
|
VIR_DOMAIN_AFFECT_LIVE,
|
||||||
from libvirt import (
|
VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT,
|
||||||
VIR_MIGRATE_LIVE,
|
VIR_DOMAIN_RUNNING,
|
||||||
VIR_MIGRATE_UNSAFE,
|
VIR_DOMAIN_XML_SECURE,
|
||||||
VIR_MIGRATE_PERSIST_DEST,
|
|
||||||
VIR_MIGRATE_UNDEFINE_SOURCE,
|
|
||||||
VIR_MIGRATE_OFFLINE,
|
|
||||||
VIR_MIGRATE_COMPRESSED,
|
|
||||||
VIR_MIGRATE_AUTO_CONVERGE,
|
VIR_MIGRATE_AUTO_CONVERGE,
|
||||||
|
VIR_MIGRATE_COMPRESSED,
|
||||||
|
VIR_MIGRATE_LIVE,
|
||||||
|
VIR_MIGRATE_OFFLINE,
|
||||||
|
VIR_MIGRATE_PERSIST_DEST,
|
||||||
VIR_MIGRATE_POSTCOPY,
|
VIR_MIGRATE_POSTCOPY,
|
||||||
|
VIR_MIGRATE_UNDEFINE_SOURCE,
|
||||||
|
VIR_MIGRATE_UNSAFE,
|
||||||
|
libvirtError,
|
||||||
)
|
)
|
||||||
from libvirt import VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT
|
from libvirt_qemu import VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT, qemuAgentCommand
|
||||||
from libvirt_qemu import qemuAgentCommand, VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT
|
|
||||||
except:
|
except:
|
||||||
from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE, VIR_MIGRATE_LIVE
|
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_name = disk.xpath("source/@pool")[0]
|
||||||
s = self.wvm.storagePoolLookupByName(s_name)
|
s = self.wvm.storagePoolLookupByName(s_name)
|
||||||
src_file = s.storageVolLookupByName(v).path()
|
src_file = s.storageVolLookupByName(v).path()
|
||||||
try:
|
|
||||||
|
with contextlib.suppress(Exception):
|
||||||
disk_format = disk.xpath("driver/@type")[0]
|
disk_format = disk.xpath("driver/@type")[0]
|
||||||
except:
|
|
||||||
pass
|
with contextlib.suppress(Exception):
|
||||||
try:
|
|
||||||
disk_cache = disk.xpath("driver/@cache")[0]
|
disk_cache = disk.xpath("driver/@cache")[0]
|
||||||
except:
|
|
||||||
pass
|
with contextlib.suppress(Exception):
|
||||||
try:
|
|
||||||
disk_io = disk.xpath("driver/@io")[0]
|
disk_io = disk.xpath("driver/@io")[0]
|
||||||
except:
|
|
||||||
pass
|
with contextlib.suppress(Exception):
|
||||||
try:
|
|
||||||
disk_discard = disk.xpath("driver/@discard")[0]
|
disk_discard = disk.xpath("driver/@discard")[0]
|
||||||
except:
|
|
||||||
pass
|
with contextlib.suppress(Exception):
|
||||||
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
|
readonly = True if disk.xpath("readonly") else False
|
||||||
shareable = True if disk.xpath("shareable") else False
|
shareable = True if disk.xpath("shareable") else False
|
||||||
|
@ -572,15 +566,14 @@ class wvmInstance(wvmConnect):
|
||||||
try:
|
try:
|
||||||
dev = media.xpath("target/@dev")[0]
|
dev = media.xpath("target/@dev")[0]
|
||||||
bus = media.xpath("target/@bus")[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]
|
src_file = media.xpath("source/@file")[0]
|
||||||
vol = self.get_volume_by_path(src_file)
|
vol = self.get_volume_by_path(src_file)
|
||||||
volume = vol.name()
|
volume = vol.name()
|
||||||
stg = vol.storagePoolLookupByVolume()
|
stg = vol.storagePoolLookupByVolume()
|
||||||
storage = stg.name()
|
storage = stg.name()
|
||||||
except:
|
|
||||||
src_file = None
|
|
||||||
volume = src_file
|
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
|
@ -1083,11 +1076,10 @@ class wvmInstance(wvmConnect):
|
||||||
graphic.set("listen", listener_addr)
|
graphic.set("listen", listener_addr)
|
||||||
listen.set("address", listener_addr)
|
listen.set("address", listener_addr)
|
||||||
else:
|
else:
|
||||||
try:
|
with contextlib.suppress(Exception):
|
||||||
graphic.attrib.pop("listen")
|
graphic.attrib.pop("listen")
|
||||||
listen.attrib.pop("address")
|
listen.attrib.pop("address")
|
||||||
except:
|
|
||||||
pass
|
|
||||||
newxml = ElementTree.tostring(root).decode()
|
newxml = ElementTree.tostring(root).decode()
|
||||||
return self._defineXML(newxml)
|
return self._defineXML(newxml)
|
||||||
|
|
||||||
|
@ -1158,10 +1150,9 @@ class wvmInstance(wvmConnect):
|
||||||
if passwd:
|
if passwd:
|
||||||
graphic.set("passwd", passwd)
|
graphic.set("passwd", passwd)
|
||||||
else:
|
else:
|
||||||
try:
|
with contextlib.suppress(Exception):
|
||||||
graphic.attrib.pop("passwd")
|
graphic.attrib.pop("passwd")
|
||||||
except:
|
|
||||||
pass
|
|
||||||
newxml = ElementTree.tostring(root).decode()
|
newxml = ElementTree.tostring(root).decode()
|
||||||
return self._defineXML(newxml)
|
return self._defineXML(newxml)
|
||||||
|
|
||||||
|
@ -1177,10 +1168,9 @@ class wvmInstance(wvmConnect):
|
||||||
if keymap != "auto":
|
if keymap != "auto":
|
||||||
graphic.set("keymap", keymap)
|
graphic.set("keymap", keymap)
|
||||||
else:
|
else:
|
||||||
try:
|
with contextlib.suppress(Exception):
|
||||||
graphic.attrib.pop("keymap")
|
graphic.attrib.pop("keymap")
|
||||||
except:
|
|
||||||
pass
|
|
||||||
newxml = ElementTree.tostring(root).decode()
|
newxml = ElementTree.tostring(root).decode()
|
||||||
self._defineXML(newxml)
|
self._defineXML(newxml)
|
||||||
|
|
||||||
|
@ -1279,10 +1269,9 @@ class wvmInstance(wvmConnect):
|
||||||
for storage in storages:
|
for storage in storages:
|
||||||
stg = self.get_storage(storage)
|
stg = self.get_storage(storage)
|
||||||
if stg.info()[0] != 0:
|
if stg.info()[0] != 0:
|
||||||
try:
|
with contextlib.suppress(Exception):
|
||||||
stg.refresh(0)
|
stg.refresh(0)
|
||||||
except:
|
|
||||||
pass
|
|
||||||
for img in stg.listVolumes():
|
for img in stg.listVolumes():
|
||||||
if img.lower().endswith(".iso"):
|
if img.lower().endswith(".iso"):
|
||||||
iso.append(img)
|
iso.append(img)
|
||||||
|
@ -1424,10 +1413,10 @@ class wvmInstance(wvmConnect):
|
||||||
device_name = elm.get("dev")
|
device_name = elm.get("dev")
|
||||||
if device_name:
|
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]
|
|
||||||
except:
|
|
||||||
meta_prealloc = False
|
meta_prealloc = False
|
||||||
|
with contextlib.suppress(Exception):
|
||||||
|
meta_prealloc = clone_data["meta-" + device_name]
|
||||||
|
|
||||||
elm.set("dev", device_name)
|
elm.set("dev", device_name)
|
||||||
|
|
||||||
elm = disk.find("source")
|
elm = disk.find("source")
|
||||||
|
@ -1522,12 +1511,7 @@ class wvmInstance(wvmConnect):
|
||||||
return bridge_name
|
return bridge_name
|
||||||
|
|
||||||
def add_network(
|
def add_network(
|
||||||
self,
|
self, mac_address, source, source_type="net", model="virtio", nwfilter=None
|
||||||
mac_address,
|
|
||||||
source,
|
|
||||||
source_type="net",
|
|
||||||
model="virtio",
|
|
||||||
nwfilter=None
|
|
||||||
):
|
):
|
||||||
|
|
||||||
if source_type == "net":
|
if source_type == "net":
|
||||||
|
@ -1588,11 +1572,7 @@ class wvmInstance(wvmConnect):
|
||||||
status = self.delete_network(net_mac)
|
status = self.delete_network(net_mac)
|
||||||
try:
|
try:
|
||||||
self.add_network(
|
self.add_network(
|
||||||
net_mac,
|
net_mac, net_source, net_source_type, net_model, net_filter
|
||||||
net_source,
|
|
||||||
net_source_type,
|
|
||||||
net_model,
|
|
||||||
net_filter
|
|
||||||
)
|
)
|
||||||
except libvirtError:
|
except libvirtError:
|
||||||
if status is not None:
|
if status is not None:
|
||||||
|
|
|
@ -1,17 +1,29 @@
|
||||||
from xml.etree import ElementTree
|
from xml.etree import ElementTree
|
||||||
|
|
||||||
from libvirt import VIR_INTERFACE_XML_INACTIVE
|
from libvirt import VIR_INTERFACE_XML_INACTIVE
|
||||||
|
|
||||||
from vrtManager import util
|
from vrtManager import util
|
||||||
from vrtManager.connection import wvmConnect
|
from vrtManager.connection import wvmConnect
|
||||||
|
|
||||||
|
|
||||||
class wvmInterfaces(wvmConnect):
|
class wvmInterfaces(wvmConnect):
|
||||||
|
|
||||||
def define_iface(self, xml, flag=0):
|
def define_iface(self, xml, flag=0):
|
||||||
self.wvm.interfaceDefineXML(xml, flag)
|
self.wvm.interfaceDefineXML(xml, flag)
|
||||||
|
|
||||||
def create_iface(
|
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}'>
|
xml = f"""<interface type='{itype}' name='{name}'>
|
||||||
<start mode='{mode}'/>"""
|
<start mode='{mode}'/>"""
|
||||||
|
@ -74,15 +86,21 @@ class wvmInterface(wvmConnect):
|
||||||
def get_ipv4_type(self):
|
def get_ipv4_type(self):
|
||||||
try:
|
try:
|
||||||
xml = self._XMLDesc(VIR_INTERFACE_XML_INACTIVE)
|
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"
|
return "static" if ipaddr else "dhcp"
|
||||||
except Exception:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_ipv4(self):
|
def get_ipv4(self):
|
||||||
xml = self._XMLDesc()
|
xml = self._XMLDesc()
|
||||||
int_ipv4_ip = util.get_xml_path(xml, "/interface/protocol[@family='ipv4']/ip/@address")
|
int_ipv4_ip = util.get_xml_path(
|
||||||
int_ipv4_mask = util.get_xml_path(xml, "/interface/protocol[@family='ipv4']/ip/@prefix")
|
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:
|
if not int_ipv4_ip or not int_ipv4_mask:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
|
@ -91,15 +109,21 @@ class wvmInterface(wvmConnect):
|
||||||
def get_ipv6_type(self):
|
def get_ipv6_type(self):
|
||||||
try:
|
try:
|
||||||
xml = self._XMLDesc(VIR_INTERFACE_XML_INACTIVE)
|
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"
|
return "static" if ipaddr else "dhcp"
|
||||||
except Exception:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_ipv6(self):
|
def get_ipv6(self):
|
||||||
xml = self._XMLDesc()
|
xml = self._XMLDesc()
|
||||||
int_ipv6_ip = util.get_xml_path(xml, "/interface/protocol[@family='ipv6']/ip/@address")
|
int_ipv6_ip = util.get_xml_path(
|
||||||
int_ipv6_mask = util.get_xml_path(xml, "/interface/protocol[@family='ipv6']/ip/@prefix")
|
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:
|
if not int_ipv6_ip or not int_ipv6_mask:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
|
@ -133,7 +157,15 @@ class wvmInterface(wvmConnect):
|
||||||
mac = iface.find("mac")
|
mac = iface.find("mac")
|
||||||
if mac is not None:
|
if mac is not None:
|
||||||
address = mac.get("address")
|
address = mac.get("address")
|
||||||
ifaces.append({"name": name, "type": if_type, "state": state, "speed": speed, "mac": address})
|
ifaces.append(
|
||||||
|
{
|
||||||
|
"name": name,
|
||||||
|
"type": if_type,
|
||||||
|
"state": state,
|
||||||
|
"speed": speed,
|
||||||
|
"mac": address,
|
||||||
|
}
|
||||||
|
)
|
||||||
return ifaces
|
return ifaces
|
||||||
|
|
||||||
def get_details(self):
|
def get_details(self):
|
||||||
|
|
|
@ -242,7 +242,7 @@ class wvmStorage(wvmConnect):
|
||||||
def refresh(self):
|
def refresh(self):
|
||||||
return self.pool.refresh(0)
|
return self.pool.refresh(0)
|
||||||
|
|
||||||
def get_volume_details(self, volname):
|
def get_volumes_details(self):
|
||||||
with contextlib.suppress(Exception):
|
with contextlib.suppress(Exception):
|
||||||
self.refresh()
|
self.refresh()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue