mirror of
https://github.com/retspen/webvirtcloud
synced 2024-10-31 19:44:16 +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
|
||||
"""
|
||||
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 (
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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,31 +156,8 @@ 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,
|
||||
)
|
||||
|
||||
disk_device_types = conn.get_disk_device_types(arch, machine)
|
||||
|
||||
if disk in disk_device_types:
|
||||
if disk == "disk":
|
||||
data["bus"] = sorted(disk_device_types)
|
||||
elif disk == "cdrom":
|
||||
data["bus"] = ["ide", "sata", "scsi"]
|
||||
elif disk == "floppy":
|
||||
data["bus"] = ["fdc"]
|
||||
elif disk == "lun":
|
||||
data["bus"] = ["scsi"]
|
||||
except libvirtError:
|
||||
pass
|
||||
|
||||
return HttpResponse(json.dumps(data))
|
||||
comp_mgr = ComputeManager(compute_id)
|
||||
return HttpResponse(comp_mgr.get_disk_buses(arch, machine, disk))
|
||||
|
||||
|
||||
def get_compute_machine_types(request, compute_id, arch):
|
||||
|
@ -212,20 +167,8 @@ def get_compute_machine_types(request, compute_id, arch):
|
|||
:param arch:
|
||||
:return:
|
||||
"""
|
||||
data = dict()
|
||||
try:
|
||||
compute = get_object_or_404(Compute, pk=compute_id)
|
||||
conn = wvmConnect(
|
||||
compute.hostname,
|
||||
compute.login,
|
||||
compute.password,
|
||||
compute.type,
|
||||
)
|
||||
data["machines"] = conn.get_machine_types(arch)
|
||||
except libvirtError:
|
||||
pass
|
||||
|
||||
return HttpResponse(json.dumps(data))
|
||||
comp_mgr = ComputeManager(compute_id)
|
||||
return HttpResponse(comp_mgr.get_machine_types(arch))
|
||||
|
||||
|
||||
def get_compute_video_models(request, compute_id, arch, machine):
|
||||
|
@ -236,20 +179,8 @@ def get_compute_video_models(request, compute_id, arch, machine):
|
|||
: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))
|
||||
comp_mgr = ComputeManager(compute_id)
|
||||
return HttpResponse(comp_mgr.get_video_models(arch, machine))
|
||||
|
||||
|
||||
def get_dom_capabilities(request, compute_id, arch, machine):
|
||||
|
@ -260,18 +191,88 @@ def get_dom_capabilities(request, compute_id, arch, machine):
|
|||
: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
|
||||
comp_mgr = ComputeManager(compute_id)
|
||||
return HttpResponse(comp_mgr.get_dom_capabilities(arch, machine))
|
||||
|
||||
return HttpResponse(json.dumps(data))
|
||||
|
||||
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,
|
||||
)
|
||||
|
||||
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":
|
||||
data["bus"] = sorted(disk_device_types)
|
||||
elif disk == "cdrom":
|
||||
data["bus"] = ["ide", "sata", "scsi"]
|
||||
elif disk == "floppy":
|
||||
data["bus"] = ["fdc"]
|
||||
elif disk == "lun":
|
||||
data["bus"] = ["scsi"]
|
||||
except libvirtError:
|
||||
pass
|
||||
|
||||
return json.dumps(data)
|
||||
|
||||
def compute_graph(self):
|
||||
try:
|
||||
conn = wvmHostDetails(
|
||||
self.compute.hostname,
|
||||
self.compute.login,
|
||||
self.compute.password,
|
||||
self.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
|
||||
|
||||
return json.dumps(
|
||||
{
|
||||
"cpudata": cpu_usage["usage"],
|
||||
"memdata": mem_usage,
|
||||
"timeline": current_time,
|
||||
}
|
||||
)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = ["eth0", "eth1"]
|
||||
with contextlib.suppress(Exception):
|
||||
netdevs = conn.get_net_devices()
|
||||
except:
|
||||
netdevs = ["eth0", "eth1"]
|
||||
|
||||
for iface in ifaces:
|
||||
interf = wvmInterface(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from rest_framework import serializers
|
||||
from networks.models import Networks
|
||||
from rest_framework import serializers
|
||||
|
||||
|
||||
class NetworksSerializer(serializers.ModelSerializer):
|
||||
|
|
|
@ -1,26 +1,28 @@
|
|||
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):
|
||||
"""
|
||||
A viewset for listing retrieving networks.
|
||||
"""
|
||||
|
||||
|
||||
def list(self, request, compute_pk=None):
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ from django.utils.translation import gettext_lazy as _
|
|||
|
||||
class AddNetPool(forms.Form):
|
||||
name = forms.CharField(
|
||||
error_messages={"required": _("No pool name has been entered")},
|
||||
error_messages={"required": _("No pool name has been entered")},
|
||||
max_length=20
|
||||
)
|
||||
subnet = forms.CharField(
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -1,36 +1,40 @@
|
|||
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):
|
||||
"""
|
||||
A viewset for listing retrieving storages.
|
||||
"""
|
||||
|
||||
|
||||
def list(self, request, compute_pk=None):
|
||||
|
||||
|
||||
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,14 +102,17 @@ class VolumeViewSet(viewsets.ViewSet):
|
|||
"""
|
||||
A simple ViewSet for listing or retrieving Storage Volumes.
|
||||
"""
|
||||
|
||||
serializer_class = VolumeSerializer
|
||||
lookup_value_regex = "[^/]+"
|
||||
|
||||
def list(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
|
||||
)
|
||||
state = conn.is_active()
|
||||
|
||||
if state:
|
||||
|
@ -105,29 +121,37 @@ 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:
|
||||
volume_queryset = conn.get_volume_details(pk)
|
||||
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"})
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import string
|
||||
import contextlib
|
||||
import string
|
||||
|
||||
from vrtManager import util
|
||||
from vrtManager.connection import wvmConnect
|
||||
|
|
|
@ -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 = False
|
||||
with contextlib.suppress(Exception):
|
||||
meta_prealloc = clone_data["meta-" + device_name]
|
||||
except:
|
||||
meta_prealloc = False
|
||||
|
||||
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:
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
Loading…
Reference in a new issue