2016-02-11 13:48:41 +00:00
|
|
|
import os
|
2015-03-20 10:06:32 +00:00
|
|
|
import time
|
|
|
|
import json
|
2015-05-20 13:44:30 +00:00
|
|
|
import socket
|
|
|
|
import crypt
|
2016-09-06 11:01:45 +00:00
|
|
|
import re
|
2017-07-19 13:34:03 +00:00
|
|
|
import string
|
2018-07-26 09:35:37 +00:00
|
|
|
import random
|
2015-03-12 14:15:36 +00:00
|
|
|
from bisect import insort
|
2015-03-20 10:06:32 +00:00
|
|
|
from django.http import HttpResponse, HttpResponseRedirect
|
2020-01-24 07:09:46 +00:00
|
|
|
from django.urls import reverse
|
2015-04-02 12:39:40 +00:00
|
|
|
from django.shortcuts import render, get_object_or_404
|
2015-03-12 14:15:36 +00:00
|
|
|
from django.utils.translation import ugettext_lazy as _
|
2015-02-27 08:53:51 +00:00
|
|
|
from computes.models import Compute
|
2015-03-02 15:31:25 +00:00
|
|
|
from instances.models import Instance
|
2020-05-28 21:43:26 +00:00
|
|
|
from appsettings.models import AppSettings
|
2017-09-15 10:40:37 +00:00
|
|
|
from django.contrib.auth.models import User
|
2015-05-27 13:23:49 +00:00
|
|
|
from accounts.models import UserInstance, UserSSHKey
|
2015-02-27 08:53:51 +00:00
|
|
|
from vrtManager.hostdetails import wvmHostDetails
|
2015-03-11 12:54:34 +00:00
|
|
|
from vrtManager.instance import wvmInstance, wvmInstances
|
2015-02-27 08:53:51 +00:00
|
|
|
from vrtManager.connection import connection_manager
|
2017-07-19 13:34:03 +00:00
|
|
|
from vrtManager.create import wvmCreate
|
2018-10-24 09:04:05 +00:00
|
|
|
from vrtManager.storage import wvmStorage
|
2016-05-08 10:24:43 +00:00
|
|
|
from vrtManager.util import randomPasswd
|
2019-12-13 13:47:51 +00:00
|
|
|
from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE, VIR_DOMAIN_UNDEFINE_KEEP_NVRAM, VIR_DOMAIN_UNDEFINE_NVRAM
|
2015-03-18 13:48:29 +00:00
|
|
|
from logs.views import addlogmsg
|
2016-03-23 08:00:42 +00:00
|
|
|
from django.conf import settings
|
2018-07-24 10:52:47 +00:00
|
|
|
from django.contrib import messages
|
2019-11-29 11:48:24 +00:00
|
|
|
from collections import OrderedDict
|
2015-02-27 08:53:51 +00:00
|
|
|
|
2019-09-10 06:45:49 +00:00
|
|
|
|
2015-02-27 08:53:51 +00:00
|
|
|
def index(request):
|
|
|
|
"""
|
|
|
|
:param request:
|
|
|
|
:return:
|
|
|
|
"""
|
2018-09-28 10:33:21 +00:00
|
|
|
return HttpResponseRedirect(reverse('allinstances'))
|
2015-02-27 08:53:51 +00:00
|
|
|
|
|
|
|
|
2018-09-28 10:33:21 +00:00
|
|
|
def allinstances(request):
|
2015-02-27 08:53:51 +00:00
|
|
|
"""
|
2018-09-28 10:33:21 +00:00
|
|
|
INSTANCES LIST FOR ALL HOSTS
|
2015-02-27 08:53:51 +00:00
|
|
|
:param request:
|
|
|
|
:return:
|
|
|
|
"""
|
2019-11-29 11:48:24 +00:00
|
|
|
all_host_vms = OrderedDict()
|
2018-09-28 10:33:21 +00:00
|
|
|
error_messages = []
|
2018-07-20 06:54:26 +00:00
|
|
|
computes = Compute.objects.all().order_by("name")
|
2020-05-19 16:53:54 +00:00
|
|
|
computes_data = get_hosts_status(computes)
|
2015-02-27 08:53:51 +00:00
|
|
|
|
2015-03-02 15:31:25 +00:00
|
|
|
if not request.user.is_superuser:
|
2018-09-28 10:33:21 +00:00
|
|
|
all_user_vms = get_user_instances(request)
|
2015-03-02 15:31:25 +00:00
|
|
|
else:
|
2015-03-11 12:54:34 +00:00
|
|
|
for comp in computes:
|
2018-09-28 10:33:21 +00:00
|
|
|
try:
|
2019-01-17 07:38:53 +00:00
|
|
|
all_host_vms.update(get_host_instances(request, comp))
|
2018-09-28 10:33:21 +00:00
|
|
|
except libvirtError as lib_err:
|
|
|
|
error_messages.append(lib_err)
|
2015-02-27 08:53:51 +00:00
|
|
|
|
2015-03-11 12:54:34 +00:00
|
|
|
if request.method == 'POST':
|
|
|
|
try:
|
2019-01-17 07:38:53 +00:00
|
|
|
return instances_actions(request)
|
2018-09-28 10:33:21 +00:00
|
|
|
except libvirtError as lib_err:
|
|
|
|
error_messages.append(lib_err)
|
2020-03-16 13:59:45 +00:00
|
|
|
addlogmsg(request.user.username, request.POST.get("name", "instance"), lib_err)
|
2015-03-27 09:53:13 +00:00
|
|
|
|
2020-05-28 21:43:26 +00:00
|
|
|
view_style = AppSettings.objects.get(key="VIEW_INSTANCES_LIST_STYLE").value
|
2015-03-27 09:53:13 +00:00
|
|
|
|
2018-09-28 10:33:21 +00:00
|
|
|
return render(request, 'allinstances.html', locals())
|
2016-04-16 13:06:39 +00:00
|
|
|
|
2015-03-27 09:53:13 +00:00
|
|
|
|
2018-09-28 10:33:21 +00:00
|
|
|
def instances(request, compute_id):
|
|
|
|
"""
|
|
|
|
:param request:
|
2019-10-30 08:05:50 +00:00
|
|
|
:param compute_id
|
2018-09-28 10:33:21 +00:00
|
|
|
:return:
|
|
|
|
"""
|
2019-11-29 11:48:24 +00:00
|
|
|
all_host_vms = OrderedDict()
|
2018-09-28 10:33:21 +00:00
|
|
|
error_messages = []
|
|
|
|
compute = get_object_or_404(Compute, pk=compute_id)
|
2015-03-27 09:53:13 +00:00
|
|
|
|
2018-09-28 10:33:21 +00:00
|
|
|
if not request.user.is_superuser:
|
|
|
|
all_user_vms = get_user_instances(request)
|
|
|
|
else:
|
|
|
|
try:
|
|
|
|
all_host_vms = get_host_instances(request, compute)
|
|
|
|
except libvirtError as lib_err:
|
|
|
|
error_messages.append(lib_err)
|
2015-03-27 09:53:13 +00:00
|
|
|
|
2018-09-28 10:33:21 +00:00
|
|
|
if request.method == 'POST':
|
|
|
|
try:
|
2019-01-17 07:38:53 +00:00
|
|
|
return instances_actions(request)
|
2015-03-11 12:54:34 +00:00
|
|
|
except libvirtError as lib_err:
|
|
|
|
error_messages.append(lib_err)
|
2020-03-16 13:59:45 +00:00
|
|
|
addlogmsg(request.user.username, request.POST.get("name", "instance"), lib_err)
|
2015-03-11 12:54:34 +00:00
|
|
|
|
2015-04-02 13:20:46 +00:00
|
|
|
return render(request, 'instances.html', locals())
|
2015-02-27 08:53:51 +00:00
|
|
|
|
|
|
|
|
2015-03-12 14:15:36 +00:00
|
|
|
def instance(request, compute_id, vname):
|
2015-02-27 08:53:51 +00:00
|
|
|
"""
|
|
|
|
:param request:
|
2019-09-10 13:05:23 +00:00
|
|
|
:param compute_id:
|
|
|
|
:param vname:
|
2015-02-27 08:53:51 +00:00
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
|
2015-03-16 09:57:55 +00:00
|
|
|
error_messages = []
|
2015-04-02 12:39:40 +00:00
|
|
|
compute = get_object_or_404(Compute, pk=compute_id)
|
2018-04-27 12:12:56 +00:00
|
|
|
computes = Compute.objects.all().order_by('name')
|
2018-02-14 14:22:57 +00:00
|
|
|
computes_count = computes.count()
|
2017-09-15 10:40:37 +00:00
|
|
|
users = User.objects.all().order_by('username')
|
2015-05-27 13:23:49 +00:00
|
|
|
publickeys = UserSSHKey.objects.filter(user_id=request.user.id)
|
2020-05-28 21:43:26 +00:00
|
|
|
appsettings = AppSettings.objects.all()
|
2018-06-15 12:13:50 +00:00
|
|
|
keymaps = settings.QEMU_KEYMAPS
|
2020-05-28 21:43:26 +00:00
|
|
|
console_types = appsettings.get(key="QEMU_CONSOLE_DEFAULT_TYPE").choices_as_list
|
2018-06-15 12:13:50 +00:00
|
|
|
console_listen_addresses = settings.QEMU_CONSOLE_LISTEN_ADDRESSES
|
2020-05-28 21:43:26 +00:00
|
|
|
bottom_bar = appsettings.get(key="VIEW_INSTANCE_DETAIL_BOTTOM_BAR").value
|
2015-03-16 09:57:55 +00:00
|
|
|
try:
|
2018-07-20 06:54:26 +00:00
|
|
|
userinstance = UserInstance.objects.get(instance__compute_id=compute_id,
|
2018-09-28 10:33:21 +00:00
|
|
|
instance__name=vname,
|
|
|
|
user__id=request.user.id)
|
2015-03-16 09:57:55 +00:00
|
|
|
except UserInstance.DoesNotExist:
|
2018-07-20 06:54:26 +00:00
|
|
|
userinstance = None
|
2015-03-16 09:57:55 +00:00
|
|
|
|
|
|
|
if not request.user.is_superuser:
|
2018-07-20 06:54:26 +00:00
|
|
|
if not userinstance:
|
2015-03-16 09:57:55 +00:00
|
|
|
return HttpResponseRedirect(reverse('index'))
|
|
|
|
|
2015-11-24 08:53:13 +00:00
|
|
|
def filesizefstr(size_str):
|
|
|
|
if size_str == '':
|
|
|
|
return 0
|
2020-03-16 13:59:45 +00:00
|
|
|
size_str = size_str.upper().replace("B", "")
|
2020-04-24 16:34:29 +00:00
|
|
|
if size_str[-1] == 'K':
|
2020-03-16 13:59:45 +00:00
|
|
|
return int(float(size_str[:-1])) << 10
|
2020-04-24 16:34:29 +00:00
|
|
|
elif size_str[-1] == 'M':
|
2020-03-16 13:59:45 +00:00
|
|
|
return int(float(size_str[:-1])) << 20
|
2020-04-24 16:34:29 +00:00
|
|
|
elif size_str[-1] == 'G':
|
2020-03-16 13:59:45 +00:00
|
|
|
return int(float(size_str[:-1])) << 30
|
2020-04-24 16:34:29 +00:00
|
|
|
elif size_str[-1] == 'T':
|
2020-03-16 13:59:45 +00:00
|
|
|
return int(float(size_str[:-1])) << 40
|
2020-04-24 16:34:29 +00:00
|
|
|
elif size_str[-1] == 'P':
|
2020-03-16 13:59:45 +00:00
|
|
|
return int(float(size_str[:-1])) << 50
|
2015-11-24 08:53:13 +00:00
|
|
|
else:
|
2020-03-16 13:59:45 +00:00
|
|
|
return int(float(size_str))
|
2015-03-12 14:15:36 +00:00
|
|
|
|
2016-03-23 08:00:42 +00:00
|
|
|
def get_clone_free_names(size=10):
|
2020-05-28 21:43:26 +00:00
|
|
|
prefix = appsettings.get(key="CLONE_INSTANCE_DEFAULT_PREFIX").value
|
2016-03-23 08:00:42 +00:00
|
|
|
free_names = []
|
|
|
|
existing_names = [i.name for i in Instance.objects.filter(name__startswith=prefix)]
|
|
|
|
index = 1
|
|
|
|
while len(free_names) < size:
|
|
|
|
new_name = prefix + str(index)
|
|
|
|
if new_name not in existing_names:
|
|
|
|
free_names.append(new_name)
|
|
|
|
index += 1
|
|
|
|
return free_names
|
|
|
|
|
2016-03-31 11:12:52 +00:00
|
|
|
def check_user_quota(instance, cpu, memory, disk_size):
|
2018-09-06 12:26:29 +00:00
|
|
|
ua = request.user.userattributes
|
|
|
|
msg = ""
|
|
|
|
|
|
|
|
if request.user.is_superuser:
|
|
|
|
return msg
|
|
|
|
|
2016-03-31 11:12:52 +00:00
|
|
|
user_instances = UserInstance.objects.filter(user_id=request.user.id, instance__is_template=False)
|
2018-02-14 14:22:57 +00:00
|
|
|
instance += user_instances.count()
|
2016-03-23 12:25:28 +00:00
|
|
|
for usr_inst in user_instances:
|
|
|
|
if connection_manager.host_is_up(usr_inst.instance.compute.type,
|
|
|
|
usr_inst.instance.compute.hostname):
|
2020-04-06 11:13:10 +00:00
|
|
|
conn = wvmInstance(usr_inst.instance.compute.hostname,
|
2018-09-28 10:33:21 +00:00
|
|
|
usr_inst.instance.compute.login,
|
|
|
|
usr_inst.instance.compute.password,
|
|
|
|
usr_inst.instance.compute.type,
|
|
|
|
usr_inst.instance.name)
|
2016-03-31 11:12:52 +00:00
|
|
|
cpu += int(conn.get_vcpu())
|
|
|
|
memory += int(conn.get_memory())
|
2018-10-24 09:04:05 +00:00
|
|
|
for disk in conn.get_disk_devices():
|
2017-06-26 12:45:12 +00:00
|
|
|
if disk['size']:
|
2018-09-28 10:33:21 +00:00
|
|
|
disk_size += int(disk['size']) >> 30
|
|
|
|
|
2016-03-23 12:25:28 +00:00
|
|
|
if ua.max_instances > 0 and instance > ua.max_instances:
|
2020-05-28 21:43:26 +00:00
|
|
|
quota_debug = appsettings.get(key="QUOTA_DEBUG").value
|
2016-03-31 11:12:52 +00:00
|
|
|
msg = "instance"
|
2020-05-28 21:43:26 +00:00
|
|
|
if quota_debug:
|
|
|
|
msg += f" ({instance} > {ua.max_instances})"
|
2016-03-23 12:25:28 +00:00
|
|
|
if ua.max_cpus > 0 and cpu > ua.max_cpus:
|
2016-03-31 11:12:52 +00:00
|
|
|
msg = "cpu"
|
2020-05-28 21:43:26 +00:00
|
|
|
if quota_debug:
|
|
|
|
msg += f" ({cpu} > {ua.max_cpus})"
|
2016-03-23 12:25:28 +00:00
|
|
|
if ua.max_memory > 0 and memory > ua.max_memory:
|
2016-03-31 11:12:52 +00:00
|
|
|
msg = "memory"
|
2020-05-28 21:43:26 +00:00
|
|
|
if quota_debug:
|
|
|
|
msg += f" ({memory} > {ua.max_memory})"
|
2016-03-31 11:12:52 +00:00
|
|
|
if ua.max_disk_size > 0 and disk_size > ua.max_disk_size:
|
|
|
|
msg = "disk"
|
2020-05-28 21:43:26 +00:00
|
|
|
if quota_debug:
|
|
|
|
msg += f" ({disk_size} > {ua.max_disk_size})"
|
2016-03-31 11:12:52 +00:00
|
|
|
return msg
|
2016-03-23 08:00:42 +00:00
|
|
|
|
2019-01-28 13:38:15 +00:00
|
|
|
def get_new_disk_dev(media, disks, bus):
|
2019-02-14 13:49:12 +00:00
|
|
|
existing_disk_devs = []
|
|
|
|
existing_media_devs = []
|
2017-07-19 13:34:03 +00:00
|
|
|
if bus == "virtio":
|
|
|
|
dev_base = "vd"
|
2018-11-23 12:18:32 +00:00
|
|
|
elif bus == "ide":
|
|
|
|
dev_base = "hd"
|
|
|
|
elif bus == "fdc":
|
|
|
|
dev_base = "fd"
|
2017-07-19 13:34:03 +00:00
|
|
|
else:
|
|
|
|
dev_base = "sd"
|
2019-02-14 13:49:12 +00:00
|
|
|
|
|
|
|
if disks:
|
|
|
|
existing_disk_devs = [disk['dev'] for disk in disks]
|
|
|
|
|
2018-11-23 12:18:32 +00:00
|
|
|
# cd-rom bus could be virtio/sata, because of that we should check it also
|
2019-02-14 13:49:12 +00:00
|
|
|
if media:
|
|
|
|
existing_media_devs = [m['dev'] for m in media]
|
|
|
|
|
2020-03-16 13:59:45 +00:00
|
|
|
for al in string.ascii_lowercase:
|
|
|
|
dev = dev_base + al
|
2018-11-23 12:18:32 +00:00
|
|
|
if dev not in existing_disk_devs and dev not in existing_media_devs:
|
2017-07-19 13:34:03 +00:00
|
|
|
return dev
|
|
|
|
raise Exception(_('None available device name'))
|
2018-08-28 10:18:35 +00:00
|
|
|
|
|
|
|
def get_network_tuple(network_source_str):
|
|
|
|
network_source_pack = network_source_str.split(":", 1)
|
|
|
|
if len(network_source_pack) > 1:
|
2019-10-30 08:05:50 +00:00
|
|
|
return network_source_pack[1], network_source_pack[0]
|
2018-08-28 10:18:35 +00:00
|
|
|
else:
|
2019-10-30 08:05:50 +00:00
|
|
|
return network_source_pack[0], 'net'
|
2018-09-20 11:48:32 +00:00
|
|
|
|
2019-12-19 13:06:51 +00:00
|
|
|
def migrate_instance(new_compute, instance, live=False, unsafe=False, xml_del=False, offline=False, autoconverge=False, compress=False, postcopy=False):
|
2018-09-20 11:48:32 +00:00
|
|
|
status = connection_manager.host_is_up(new_compute.type, new_compute.hostname)
|
|
|
|
if not status:
|
|
|
|
return
|
|
|
|
if new_compute == instance.compute:
|
|
|
|
return
|
2019-12-19 10:49:41 +00:00
|
|
|
try:
|
|
|
|
conn_migrate = wvmInstances(new_compute.hostname,
|
2019-12-19 13:06:51 +00:00
|
|
|
new_compute.login,
|
|
|
|
new_compute.password,
|
|
|
|
new_compute.type)
|
2019-12-19 10:49:41 +00:00
|
|
|
|
2019-12-19 13:06:51 +00:00
|
|
|
conn_migrate.moveto(conn, instance.name, live, unsafe, xml_del, offline, autoconverge, compress, postcopy)
|
2019-12-19 10:49:41 +00:00
|
|
|
finally:
|
|
|
|
conn_migrate.close()
|
|
|
|
|
2018-09-20 11:48:32 +00:00
|
|
|
instance.compute = new_compute
|
|
|
|
instance.save()
|
2019-12-19 10:49:41 +00:00
|
|
|
|
2018-09-20 11:48:32 +00:00
|
|
|
conn_new = wvmInstance(new_compute.hostname,
|
|
|
|
new_compute.login,
|
|
|
|
new_compute.password,
|
|
|
|
new_compute.type,
|
|
|
|
instance.name)
|
|
|
|
if autostart:
|
|
|
|
conn_new.set_autostart(1)
|
|
|
|
conn_new.close()
|
|
|
|
msg = _("Migrate to %s" % new_compute.hostname)
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
|
2015-03-12 14:15:36 +00:00
|
|
|
try:
|
|
|
|
conn = wvmInstance(compute.hostname,
|
|
|
|
compute.login,
|
|
|
|
compute.password,
|
|
|
|
compute.type,
|
|
|
|
vname)
|
2019-12-23 12:48:11 +00:00
|
|
|
|
2015-03-12 14:15:36 +00:00
|
|
|
status = conn.get_status()
|
|
|
|
autostart = conn.get_autostart()
|
2019-01-15 12:55:05 +00:00
|
|
|
bootmenu = conn.get_bootmenu()
|
|
|
|
boot_order = conn.get_bootorder()
|
2019-12-13 13:47:51 +00:00
|
|
|
arch = conn.get_arch()
|
|
|
|
machine = conn.get_machine_type()
|
2019-12-19 10:49:41 +00:00
|
|
|
firmware = conn.get_loader()
|
|
|
|
nvram = conn.get_nvram()
|
2015-03-12 14:15:36 +00:00
|
|
|
vcpu = conn.get_vcpu()
|
|
|
|
cur_vcpu = conn.get_cur_vcpu()
|
2019-11-29 11:48:24 +00:00
|
|
|
vcpus = conn.get_vcpus()
|
2015-03-12 14:15:36 +00:00
|
|
|
uuid = conn.get_uuid()
|
|
|
|
memory = conn.get_memory()
|
|
|
|
cur_memory = conn.get_cur_memory()
|
2016-02-23 13:43:32 +00:00
|
|
|
title = conn.get_title()
|
2015-03-12 14:15:36 +00:00
|
|
|
description = conn.get_description()
|
2019-12-23 12:48:11 +00:00
|
|
|
networks = conn.get_net_devices()
|
2019-11-20 05:37:59 +00:00
|
|
|
qos = conn.get_all_qos()
|
2018-10-24 09:04:05 +00:00
|
|
|
disks = conn.get_disk_devices()
|
|
|
|
media = conn.get_media_devices()
|
2018-02-15 09:54:39 +00:00
|
|
|
if len(media) != 0:
|
|
|
|
media_iso = sorted(conn.get_iso_media())
|
|
|
|
else:
|
|
|
|
media_iso = []
|
2018-09-26 14:20:46 +00:00
|
|
|
|
2015-03-12 14:15:36 +00:00
|
|
|
vcpu_range = conn.get_max_cpus()
|
2018-11-20 14:07:19 +00:00
|
|
|
memory_range = [256, 512, 768, 1024, 2048, 3072, 4096, 6144, 8192, 16384]
|
2015-03-12 14:15:36 +00:00
|
|
|
if memory not in memory_range:
|
|
|
|
insort(memory_range, memory)
|
|
|
|
if cur_memory not in memory_range:
|
|
|
|
insort(memory_range, cur_memory)
|
|
|
|
telnet_port = conn.get_telnet_port()
|
|
|
|
console_type = conn.get_console_type()
|
|
|
|
console_port = conn.get_console_port()
|
|
|
|
console_keymap = conn.get_console_keymap()
|
2018-06-21 13:13:12 +00:00
|
|
|
console_listen_address = conn.get_console_listen_addr()
|
2019-12-24 14:19:11 +00:00
|
|
|
guest_agent = False if conn.get_guest_agent() is None else True
|
|
|
|
guest_agent_ready = conn.is_agent_ready()
|
2019-11-20 13:24:01 +00:00
|
|
|
video_model = conn.get_video_model()
|
2018-09-28 10:33:21 +00:00
|
|
|
snapshots = sorted(conn.get_snapshot(), reverse=True, key=lambda k: k['date'])
|
2015-03-12 14:15:36 +00:00
|
|
|
inst_xml = conn._XMLDesc(VIR_DOMAIN_XML_SECURE)
|
|
|
|
has_managed_save_image = conn.get_managed_save_image()
|
|
|
|
console_passwd = conn.get_console_passwd()
|
2016-03-23 08:00:42 +00:00
|
|
|
clone_free_names = get_clone_free_names()
|
2016-03-31 11:12:52 +00:00
|
|
|
user_quota_msg = check_user_quota(0, 0, 0, 0)
|
2017-07-19 13:34:03 +00:00
|
|
|
cache_modes = sorted(conn.get_cache_modes().items())
|
2020-01-08 08:28:46 +00:00
|
|
|
io_modes = sorted(conn.get_io_modes().items())
|
|
|
|
discard_modes = sorted(conn.get_discard_modes().items())
|
|
|
|
detect_zeroes_modes = sorted(conn.get_detect_zeroes_modes().items())
|
2020-05-28 21:43:26 +00:00
|
|
|
default_bus = appsettings.get(key="INSTANCE_VOLUME_DEFAULT_BUS").value
|
|
|
|
default_io = appsettings.get(key="INSTANCE_VOLUME_DEFAULT_IO").value
|
|
|
|
default_discard = appsettings.get(key="INSTANCE_VOLUME_DEFAULT_DISCARD").value
|
|
|
|
default_zeroes = appsettings.get(key="INSTANCE_VOLUME_DEFAULT_DETECT_ZEROES").value
|
|
|
|
default_cache = appsettings.get(key="INSTANCE_VOLUME_DEFAULT_CACHE").value
|
|
|
|
default_format = appsettings.get(key="INSTANCE_VOLUME_DEFAULT_FORMAT").value
|
|
|
|
default_disk_owner_uid = int(appsettings.get(key="INSTANCE_VOLUME_DEFAULT_OWNER_UID").value)
|
|
|
|
default_disk_owner_gid = int(appsettings.get(key="INSTANCE_VOLUME_DEFAULT_OWNER_GID").value)
|
|
|
|
|
2017-07-19 13:34:03 +00:00
|
|
|
formats = conn.get_image_formats()
|
2018-07-20 10:42:13 +00:00
|
|
|
|
2020-05-28 21:43:26 +00:00
|
|
|
show_access_root_password = appsettings.get(key="SHOW_ACCESS_ROOT_PASSWORD").value
|
|
|
|
show_access_ssh_keys = appsettings.get(key="SHOW_ACCESS_SSH_KEYS").value
|
|
|
|
clone_instance_auto_name = appsettings.get(key="CLONE_INSTANCE_AUTO_NAME").value
|
|
|
|
|
2015-03-12 14:15:36 +00:00
|
|
|
|
2015-03-16 09:57:55 +00:00
|
|
|
try:
|
|
|
|
instance = Instance.objects.get(compute_id=compute_id, name=vname)
|
|
|
|
if instance.uuid != uuid:
|
|
|
|
instance.uuid = uuid
|
|
|
|
instance.save()
|
2018-09-20 11:48:32 +00:00
|
|
|
msg = _("Fixing uuid %s" % uuid)
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2015-03-16 09:57:55 +00:00
|
|
|
except Instance.DoesNotExist:
|
|
|
|
instance = Instance(compute_id=compute_id, name=vname, uuid=uuid)
|
2015-03-12 14:15:36 +00:00
|
|
|
instance.save()
|
2018-09-20 11:48:32 +00:00
|
|
|
msg = _("Instance.DoesNotExist: Creating new instance")
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2015-03-12 14:15:36 +00:00
|
|
|
|
2016-04-28 10:50:11 +00:00
|
|
|
userinstances = UserInstance.objects.filter(instance=instance).order_by('user__username')
|
2018-11-08 11:56:31 +00:00
|
|
|
allow_admin_or_not_template = request.user.is_superuser or request.user.is_staff or not instance.is_template
|
2016-04-28 10:50:11 +00:00
|
|
|
|
2019-09-10 13:05:23 +00:00
|
|
|
# Host resources
|
|
|
|
vcpu_host = len(vcpu_range)
|
|
|
|
memory_host = conn.get_max_memory()
|
2019-12-13 13:47:51 +00:00
|
|
|
bus_host = conn.get_disk_bus_types(arch, machine)
|
|
|
|
videos_host = conn.get_video_models(arch, machine)
|
2019-09-10 13:05:23 +00:00
|
|
|
networks_host = sorted(conn.get_networks())
|
|
|
|
nwfilters_host = conn.get_nwfilters()
|
|
|
|
storages_host = sorted(conn.get_storages(True))
|
2020-01-10 14:55:42 +00:00
|
|
|
net_models_host = conn.get_network_models()
|
2019-09-10 13:05:23 +00:00
|
|
|
|
2019-12-24 06:23:49 +00:00
|
|
|
try:
|
|
|
|
interfaces_host = sorted(conn.get_ifaces())
|
|
|
|
except Exception as e:
|
|
|
|
addlogmsg(request.user.username, instance.name, e)
|
|
|
|
error_messages.append(e)
|
|
|
|
|
2015-03-12 14:15:36 +00:00
|
|
|
if request.method == 'POST':
|
2015-03-13 09:06:34 +00:00
|
|
|
if 'poweron' in request.POST:
|
2018-10-24 13:56:05 +00:00
|
|
|
if instance.is_template:
|
|
|
|
msg = _("Templates cannot be started.")
|
|
|
|
error_messages.append(msg)
|
|
|
|
else:
|
|
|
|
conn.start()
|
|
|
|
msg = _("Power On")
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#poweron')
|
2015-03-13 12:06:51 +00:00
|
|
|
|
2015-03-13 09:06:34 +00:00
|
|
|
if 'powercycle' in request.POST:
|
|
|
|
conn.force_shutdown()
|
|
|
|
conn.start()
|
2015-03-27 09:53:13 +00:00
|
|
|
msg = _("Power Cycle")
|
2015-05-18 19:00:30 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2015-03-13 09:06:34 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#powercycle')
|
2015-03-13 12:06:51 +00:00
|
|
|
|
2015-07-08 05:03:36 +00:00
|
|
|
if 'poweroff' in request.POST:
|
2015-03-27 09:53:13 +00:00
|
|
|
conn.shutdown()
|
2015-03-18 13:48:29 +00:00
|
|
|
msg = _("Power Off")
|
2015-05-18 19:00:30 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2015-03-13 09:06:34 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#poweroff')
|
2015-03-13 12:06:51 +00:00
|
|
|
|
2015-03-27 09:53:13 +00:00
|
|
|
if 'powerforce' in request.POST:
|
|
|
|
conn.force_shutdown()
|
|
|
|
msg = _("Force Off")
|
2015-05-18 19:00:30 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2015-03-27 15:12:15 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#powerforce')
|
2015-03-27 09:53:13 +00:00
|
|
|
|
2018-07-20 06:54:26 +00:00
|
|
|
if 'delete' in request.POST and (request.user.is_superuser or userinstance.is_delete):
|
2015-03-12 14:15:36 +00:00
|
|
|
if conn.get_status() == 1:
|
|
|
|
conn.force_shutdown()
|
2015-07-09 07:41:56 +00:00
|
|
|
if request.POST.get('delete_disk', ''):
|
2016-11-04 08:33:49 +00:00
|
|
|
for snap in snapshots:
|
|
|
|
conn.snapshot_delete(snap['name'])
|
2018-10-19 13:14:33 +00:00
|
|
|
conn.delete_all_disks()
|
2019-12-13 13:47:51 +00:00
|
|
|
|
|
|
|
if request.POST.get('delete_nvram', ''):
|
|
|
|
conn.delete(VIR_DOMAIN_UNDEFINE_NVRAM)
|
|
|
|
else:
|
|
|
|
conn.delete(VIR_DOMAIN_UNDEFINE_KEEP_NVRAM)
|
2015-07-09 07:41:56 +00:00
|
|
|
|
|
|
|
instance = Instance.objects.get(compute_id=compute_id, name=vname)
|
|
|
|
instance_name = instance.name
|
|
|
|
instance.delete()
|
|
|
|
|
2016-03-23 12:47:04 +00:00
|
|
|
try:
|
2018-09-28 10:33:21 +00:00
|
|
|
del_userinstance = UserInstance.objects.filter(instance__compute_id=compute_id,
|
|
|
|
instance__name=vname)
|
2015-07-09 07:41:56 +00:00
|
|
|
del_userinstance.delete()
|
2016-03-23 12:47:04 +00:00
|
|
|
except UserInstance.DoesNotExist:
|
|
|
|
pass
|
2015-07-09 07:41:56 +00:00
|
|
|
|
|
|
|
msg = _("Destroy")
|
|
|
|
addlogmsg(request.user.username, instance_name, msg)
|
|
|
|
|
2018-10-01 12:09:04 +00:00
|
|
|
return HttpResponseRedirect(reverse('allinstances'))
|
2015-03-13 12:06:51 +00:00
|
|
|
|
2015-05-20 13:44:30 +00:00
|
|
|
if 'rootpasswd' in request.POST:
|
|
|
|
passwd = request.POST.get('passwd', '')
|
|
|
|
passwd_hash = crypt.crypt(passwd, '$6$kgPoiREy')
|
2015-05-27 13:23:49 +00:00
|
|
|
data = {'action': 'password', 'passwd': passwd_hash, 'vname': vname}
|
2015-05-20 13:44:30 +00:00
|
|
|
|
2015-05-21 08:52:10 +00:00
|
|
|
if conn.get_status() == 5:
|
|
|
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
|
|
s.connect((compute.hostname, 16510))
|
|
|
|
s.send(json.dumps(data))
|
|
|
|
result = json.loads(s.recv(1024))
|
|
|
|
s.close()
|
|
|
|
msg = _("Reset root password")
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2015-05-20 13:44:30 +00:00
|
|
|
|
2015-05-21 08:52:10 +00:00
|
|
|
if result['return'] == 'success':
|
2018-07-24 10:52:47 +00:00
|
|
|
messages.success(request, msg)
|
2015-05-21 08:52:10 +00:00
|
|
|
else:
|
|
|
|
error_messages.append(msg)
|
2015-05-20 13:44:30 +00:00
|
|
|
else:
|
2018-09-21 16:07:47 +00:00
|
|
|
msg = _("Please shutdown down your instance and then try again")
|
2015-05-21 08:52:10 +00:00
|
|
|
error_messages.append(msg)
|
2015-05-20 13:44:30 +00:00
|
|
|
|
2015-05-27 13:23:49 +00:00
|
|
|
if 'addpublickey' in request.POST:
|
|
|
|
sshkeyid = request.POST.get('sshkeyid', '')
|
|
|
|
publickey = UserSSHKey.objects.get(id=sshkeyid)
|
|
|
|
data = {'action': 'publickey', 'key': publickey.keypublic, 'vname': vname}
|
|
|
|
|
|
|
|
if conn.get_status() == 5:
|
|
|
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
|
|
s.connect((compute.hostname, 16510))
|
|
|
|
s.send(json.dumps(data))
|
|
|
|
result = json.loads(s.recv(1024))
|
|
|
|
s.close()
|
|
|
|
msg = _("Installed new ssh public key %s" % publickey.keyname)
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
|
|
|
|
if result['return'] == 'success':
|
2018-07-24 10:52:47 +00:00
|
|
|
messages.success(request, msg)
|
2015-05-27 13:23:49 +00:00
|
|
|
else:
|
|
|
|
error_messages.append(msg)
|
|
|
|
else:
|
2018-09-21 16:07:47 +00:00
|
|
|
msg = _("Please shutdown down your instance and then try again")
|
2015-05-27 13:23:49 +00:00
|
|
|
error_messages.append(msg)
|
|
|
|
|
2019-08-27 14:18:33 +00:00
|
|
|
if 'resizevm_cpu' in request.POST and (
|
|
|
|
request.user.is_superuser or request.user.is_staff or userinstance.is_change):
|
|
|
|
new_vcpu = request.POST.get('vcpu', '')
|
|
|
|
new_cur_vcpu = request.POST.get('cur_vcpu', '')
|
|
|
|
|
|
|
|
quota_msg = check_user_quota(0, int(new_vcpu) - vcpu, 0, 0)
|
|
|
|
if not request.user.is_superuser and quota_msg:
|
2020-05-19 16:53:54 +00:00
|
|
|
msg = _(f"User {quota_msg} quota reached, cannot resize CPU of '{instance.name}'!")
|
2019-08-27 14:18:33 +00:00
|
|
|
error_messages.append(msg)
|
|
|
|
else:
|
|
|
|
cur_vcpu = new_cur_vcpu
|
|
|
|
vcpu = new_vcpu
|
|
|
|
conn.resize_cpu(cur_vcpu, vcpu)
|
|
|
|
msg = _("Resize CPU")
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2020-01-13 13:14:21 +00:00
|
|
|
messages.success(request, msg)
|
2019-11-20 08:41:50 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#resize')
|
2019-08-27 14:18:33 +00:00
|
|
|
|
2019-11-20 05:37:59 +00:00
|
|
|
if 'resizevm_mem' in request.POST and (request.user.is_superuser or
|
|
|
|
request.user.is_staff or
|
|
|
|
userinstance.is_change):
|
2019-08-27 14:18:33 +00:00
|
|
|
new_memory = request.POST.get('memory', '')
|
|
|
|
new_memory_custom = request.POST.get('memory_custom', '')
|
|
|
|
if new_memory_custom:
|
|
|
|
new_memory = new_memory_custom
|
|
|
|
new_cur_memory = request.POST.get('cur_memory', '')
|
|
|
|
new_cur_memory_custom = request.POST.get('cur_memory_custom', '')
|
|
|
|
if new_cur_memory_custom:
|
|
|
|
new_cur_memory = new_cur_memory_custom
|
|
|
|
quota_msg = check_user_quota(0, 0, int(new_memory) - memory, 0)
|
|
|
|
if not request.user.is_superuser and quota_msg:
|
2020-05-19 16:53:54 +00:00
|
|
|
msg = _(f"User {quota_msg} quota reached, cannot resize memory of '{instance.name}'!")
|
2019-08-27 14:18:33 +00:00
|
|
|
error_messages.append(msg)
|
|
|
|
else:
|
|
|
|
cur_memory = new_cur_memory
|
|
|
|
memory = new_memory
|
|
|
|
conn.resize_mem(cur_memory, memory)
|
|
|
|
msg = _("Resize Memory")
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2020-01-13 13:14:21 +00:00
|
|
|
messages.success(request, msg)
|
2019-11-20 08:41:50 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#resize')
|
2019-08-27 14:18:33 +00:00
|
|
|
|
|
|
|
if 'resizevm_disk' in request.POST and (
|
|
|
|
request.user.is_superuser or request.user.is_staff or userinstance.is_change):
|
2019-09-10 13:05:23 +00:00
|
|
|
disks_new = list()
|
2019-08-27 14:18:33 +00:00
|
|
|
for disk in disks:
|
|
|
|
input_disk_size = filesizefstr(request.POST.get('disk_size_' + disk['dev'], ''))
|
|
|
|
if input_disk_size > disk['size'] + (64 << 20):
|
|
|
|
disk['size_new'] = input_disk_size
|
|
|
|
disks_new.append(disk)
|
|
|
|
disk_sum = sum([disk['size'] >> 30 for disk in disks_new])
|
|
|
|
disk_new_sum = sum([disk['size_new'] >> 30 for disk in disks_new])
|
|
|
|
quota_msg = check_user_quota(0, 0, 0, disk_new_sum - disk_sum)
|
|
|
|
if not request.user.is_superuser and quota_msg:
|
2020-05-19 16:53:54 +00:00
|
|
|
msg = _(f"User {quota_msg} quota reached, cannot resize disks of '{instance.name}'!")
|
2019-08-27 14:18:33 +00:00
|
|
|
error_messages.append(msg)
|
|
|
|
else:
|
2019-09-10 06:45:49 +00:00
|
|
|
conn.resize_disk(disks_new)
|
2020-05-28 21:43:26 +00:00
|
|
|
msg = _("Disk resize")
|
2019-08-27 14:18:33 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2020-01-13 13:14:21 +00:00
|
|
|
messages.success(request, msg)
|
2019-11-20 08:41:50 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#resize')
|
2015-03-13 12:06:51 +00:00
|
|
|
|
2018-11-23 12:18:32 +00:00
|
|
|
if 'add_new_vol' in request.POST and allow_admin_or_not_template:
|
2019-09-10 06:45:49 +00:00
|
|
|
conn_create = wvmCreate(compute.hostname,
|
|
|
|
compute.login,
|
|
|
|
compute.password,
|
|
|
|
compute.type)
|
2017-07-19 13:34:03 +00:00
|
|
|
storage = request.POST.get('storage', '')
|
|
|
|
name = request.POST.get('name', '')
|
2018-09-27 06:45:10 +00:00
|
|
|
format = request.POST.get('format', default_format)
|
2017-07-19 13:34:03 +00:00
|
|
|
size = request.POST.get('size', 0)
|
2019-03-18 13:50:11 +00:00
|
|
|
meta_prealloc = True if request.POST.get('meta_prealloc', False) else False
|
2018-09-27 06:45:10 +00:00
|
|
|
bus = request.POST.get('bus', default_bus)
|
|
|
|
cache = request.POST.get('cache', default_cache)
|
2020-01-08 08:28:46 +00:00
|
|
|
target_dev = get_new_disk_dev(media, disks, bus)
|
2018-09-28 10:33:21 +00:00
|
|
|
|
2020-05-28 21:43:26 +00:00
|
|
|
source = conn_create.create_volume(storage, name, size, format, meta_prealloc, default_disk_owner_uid, default_disk_owner_gid)
|
2020-03-16 13:59:45 +00:00
|
|
|
conn.attach_disk(target_dev, source, target_bus=bus, driver_type=format, cache_mode=cache)
|
2020-05-28 21:43:26 +00:00
|
|
|
msg = _(f"Attach new disk {name} ({format})")
|
2017-07-19 13:34:03 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2018-10-19 13:14:33 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
|
|
|
|
2018-11-23 12:18:32 +00:00
|
|
|
if 'add_existing_vol' in request.POST and allow_admin_or_not_template:
|
2018-10-24 09:04:05 +00:00
|
|
|
storage = request.POST.get('selected_storage', '')
|
|
|
|
name = request.POST.get('vols', '')
|
|
|
|
bus = request.POST.get('bus', default_bus)
|
|
|
|
cache = request.POST.get('cache', default_cache)
|
|
|
|
|
2019-09-10 06:45:49 +00:00
|
|
|
conn_create = wvmStorage(compute.hostname,
|
|
|
|
compute.login,
|
|
|
|
compute.password,
|
|
|
|
compute.type,
|
|
|
|
storage)
|
2018-10-24 09:04:05 +00:00
|
|
|
|
2020-01-08 08:28:46 +00:00
|
|
|
driver_type = conn_create.get_volume_type(name)
|
2019-09-10 06:45:49 +00:00
|
|
|
path = conn_create.get_target_path()
|
2020-01-08 08:28:46 +00:00
|
|
|
target_dev = get_new_disk_dev(media, disks, bus)
|
2019-09-10 06:45:49 +00:00
|
|
|
source = path + "/" + name
|
2018-10-24 09:04:05 +00:00
|
|
|
|
2020-03-16 13:59:45 +00:00
|
|
|
conn.attach_disk(target_dev, source, target_bus=bus, driver_type=driver_type, cache_mode=cache)
|
2020-01-08 08:28:46 +00:00
|
|
|
msg = _('Attach Existing disk: ' + target_dev)
|
2018-10-25 06:55:57 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2018-10-24 09:04:05 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
|
|
|
|
2020-01-08 08:28:46 +00:00
|
|
|
if 'edit_volume' in request.POST and allow_admin_or_not_template:
|
|
|
|
target_dev = request.POST.get('dev', '')
|
|
|
|
|
|
|
|
new_path = request.POST.get('vol_path', '')
|
|
|
|
shareable = bool(request.POST.get('vol_shareable', False))
|
|
|
|
readonly = bool(request.POST.get('vol_readonly', False))
|
2020-03-16 13:59:45 +00:00
|
|
|
disk_type = request.POST.get('vol_type', '')
|
|
|
|
new_bus = request.POST.get('vol_bus', '')
|
|
|
|
bus = request.POST.get('vol_bus_old', '')
|
2020-01-08 08:28:46 +00:00
|
|
|
serial = request.POST.get('vol_serial', '')
|
|
|
|
format = request.POST.get('vol_format', '')
|
|
|
|
cache = request.POST.get('vol_cache', default_cache)
|
|
|
|
io = request.POST.get('vol_io_mode', default_io)
|
|
|
|
discard = request.POST.get('vol_discard_mode', default_discard)
|
|
|
|
zeroes = request.POST.get('vol_detect_zeroes', default_zeroes)
|
2020-03-16 13:59:45 +00:00
|
|
|
new_target_dev = get_new_disk_dev(media, disks, new_bus)
|
|
|
|
|
|
|
|
if new_bus != bus:
|
|
|
|
conn.detach_disk(target_dev)
|
|
|
|
conn.attach_disk(new_target_dev, new_path, target_bus=new_bus,
|
2020-04-24 16:34:29 +00:00
|
|
|
driver_type=format, cache_mode=cache,
|
|
|
|
readonly=readonly, shareable=shareable, serial=serial,
|
|
|
|
io_mode=io, discard_mode=discard, detect_zeroes_mode=zeroes)
|
2020-03-16 13:59:45 +00:00
|
|
|
else:
|
|
|
|
conn.edit_disk(target_dev, new_path, readonly, shareable, new_bus, serial, format,
|
|
|
|
cache, io, discard, zeroes)
|
2020-01-08 08:28:46 +00:00
|
|
|
|
|
|
|
if not conn.get_status() == 5:
|
|
|
|
messages.success(request, _("Disk changes changes are applied. " +
|
|
|
|
"But it will be activated after shutdown"))
|
|
|
|
else:
|
|
|
|
messages.success(request, _("Disk is changed successfully."))
|
|
|
|
msg = _('Edit disk: ' + target_dev)
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
|
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
|
|
|
|
2018-11-23 12:18:32 +00:00
|
|
|
if 'delete_vol' in request.POST and allow_admin_or_not_template:
|
|
|
|
storage = request.POST.get('storage', '')
|
2019-09-10 06:45:49 +00:00
|
|
|
conn_delete = wvmStorage(compute.hostname,
|
|
|
|
compute.login,
|
|
|
|
compute.password,
|
|
|
|
compute.type,
|
|
|
|
storage)
|
2018-10-19 13:14:33 +00:00
|
|
|
dev = request.POST.get('dev', '')
|
|
|
|
path = request.POST.get('path', '')
|
2018-11-23 12:18:32 +00:00
|
|
|
name = request.POST.get('name', '')
|
2018-10-19 13:14:33 +00:00
|
|
|
|
2019-10-28 08:20:39 +00:00
|
|
|
msg = _('Delete disk: ' + dev)
|
2018-11-23 12:18:32 +00:00
|
|
|
conn.detach_disk(dev)
|
2019-10-28 08:20:39 +00:00
|
|
|
try:
|
|
|
|
conn_delete.del_volume(name)
|
|
|
|
except libvirtError as err:
|
2020-03-16 13:59:45 +00:00
|
|
|
msg = _('The disk: ' + dev + ' is detached but not deleted. ' + err)
|
2019-10-28 08:20:39 +00:00
|
|
|
messages.warning(request, msg)
|
2018-10-19 13:14:33 +00:00
|
|
|
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
|
|
|
|
2018-11-23 12:18:32 +00:00
|
|
|
if 'detach_vol' in request.POST and allow_admin_or_not_template:
|
|
|
|
dev = request.POST.get('detach_vol', '')
|
2018-10-19 13:14:33 +00:00
|
|
|
path = request.POST.get('path', '')
|
2018-11-23 12:18:32 +00:00
|
|
|
conn.detach_disk(dev)
|
|
|
|
msg = _('Detach disk: ' + dev)
|
2018-10-19 13:14:33 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
2017-07-19 13:34:03 +00:00
|
|
|
|
2018-11-23 12:18:32 +00:00
|
|
|
if 'add_cdrom' in request.POST and allow_admin_or_not_template:
|
2019-12-20 13:43:14 +00:00
|
|
|
bus = request.POST.get('bus', 'ide' if machine == 'pc' else 'sata')
|
2019-01-28 13:38:15 +00:00
|
|
|
target = get_new_disk_dev(media, disks, bus)
|
2020-04-24 16:34:29 +00:00
|
|
|
conn.attach_disk(target, "", disk_device='cdrom', cache_mode='none', target_bus=bus, readonly=True)
|
2019-01-28 13:38:15 +00:00
|
|
|
msg = _('Add CD-ROM: ' + target)
|
2018-11-23 12:18:32 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2019-01-15 12:55:05 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
2018-11-23 12:18:32 +00:00
|
|
|
|
|
|
|
if 'detach_cdrom' in request.POST and allow_admin_or_not_template:
|
|
|
|
dev = request.POST.get('detach_cdrom', '')
|
|
|
|
path = request.POST.get('path', '')
|
|
|
|
conn.detach_disk(dev)
|
2020-05-19 16:53:54 +00:00
|
|
|
msg = _('Detach CD-ROM: ' + dev)
|
2018-11-23 12:18:32 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2019-01-15 12:55:05 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
2018-11-23 12:18:32 +00:00
|
|
|
|
2018-11-08 11:56:31 +00:00
|
|
|
if 'umount_iso' in request.POST and allow_admin_or_not_template:
|
2015-03-12 14:15:36 +00:00
|
|
|
image = request.POST.get('path', '')
|
|
|
|
dev = request.POST.get('umount_iso', '')
|
|
|
|
conn.umount_iso(dev, image)
|
2018-11-23 12:18:32 +00:00
|
|
|
msg = _("Mount media: " + dev)
|
2015-05-18 19:00:30 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2019-01-15 12:55:05 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
2015-03-13 12:06:51 +00:00
|
|
|
|
2018-11-08 11:56:31 +00:00
|
|
|
if 'mount_iso' in request.POST and allow_admin_or_not_template:
|
2015-03-12 14:15:36 +00:00
|
|
|
image = request.POST.get('media', '')
|
|
|
|
dev = request.POST.get('mount_iso', '')
|
|
|
|
conn.mount_iso(dev, image)
|
2018-11-23 12:18:32 +00:00
|
|
|
msg = _("Umount media: " + dev)
|
2015-05-18 19:00:30 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2019-01-15 12:55:05 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
2015-03-24 07:22:30 +00:00
|
|
|
|
2018-11-08 11:56:31 +00:00
|
|
|
if 'snapshot' in request.POST and allow_admin_or_not_template:
|
2015-03-24 07:22:30 +00:00
|
|
|
name = request.POST.get('name', '')
|
|
|
|
conn.create_snapshot(name)
|
2018-11-23 12:18:32 +00:00
|
|
|
msg = _("New snapshot :" + name)
|
2015-05-18 19:00:30 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2018-09-04 12:14:08 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#managesnapshot')
|
2015-03-13 12:06:51 +00:00
|
|
|
|
2018-11-08 11:56:31 +00:00
|
|
|
if 'delete_snapshot' in request.POST and allow_admin_or_not_template:
|
2015-03-12 14:15:36 +00:00
|
|
|
snap_name = request.POST.get('name', '')
|
|
|
|
conn.snapshot_delete(snap_name)
|
2018-11-23 12:18:32 +00:00
|
|
|
msg = _("Delete snapshot :" + snap_name)
|
2015-05-18 19:00:30 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2018-09-04 12:14:08 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#managesnapshot')
|
2015-03-13 12:06:51 +00:00
|
|
|
|
2018-11-08 11:56:31 +00:00
|
|
|
if 'revert_snapshot' in request.POST and allow_admin_or_not_template:
|
2015-03-12 14:15:36 +00:00
|
|
|
snap_name = request.POST.get('name', '')
|
|
|
|
conn.snapshot_revert(snap_name)
|
|
|
|
msg = _("Successful revert snapshot: ")
|
|
|
|
msg += snap_name
|
2018-07-24 10:52:47 +00:00
|
|
|
messages.success(request, msg)
|
2015-03-27 09:53:13 +00:00
|
|
|
msg = _("Revert snapshot")
|
2015-05-18 19:00:30 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2015-03-13 12:06:51 +00:00
|
|
|
|
2015-03-18 13:48:29 +00:00
|
|
|
if request.user.is_superuser:
|
|
|
|
if 'suspend' in request.POST:
|
2015-03-27 09:53:13 +00:00
|
|
|
conn.suspend()
|
2015-03-18 13:48:29 +00:00
|
|
|
msg = _("Suspend")
|
2015-05-18 19:00:30 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2015-03-18 13:48:29 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#resume')
|
|
|
|
|
|
|
|
if 'resume' in request.POST:
|
2015-03-27 09:53:13 +00:00
|
|
|
conn.resume()
|
2015-03-18 13:48:29 +00:00
|
|
|
msg = _("Resume")
|
2015-05-18 19:00:30 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2015-03-18 13:48:29 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#suspend')
|
|
|
|
|
2019-11-29 11:48:24 +00:00
|
|
|
if 'set_vcpu' in request.POST:
|
|
|
|
id = request.POST.get('id', '')
|
|
|
|
enabled = request.POST.get('set_vcpu', '')
|
|
|
|
if enabled == 'True':
|
|
|
|
conn.set_vcpu(id, 1)
|
|
|
|
else:
|
|
|
|
conn.set_vcpu(id, 0)
|
|
|
|
msg = _("vCPU {} is enabled={}".format(id, enabled))
|
|
|
|
messages.success(request, msg)
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#resize')
|
|
|
|
|
|
|
|
if 'set_vcpu_hotplug' in request.POST:
|
|
|
|
status = request.POST.get('vcpu_hotplug', '')
|
2020-05-19 16:53:54 +00:00
|
|
|
msg = _("VCPU Hot-plug is enabled={}".format(status))
|
2019-11-29 11:48:24 +00:00
|
|
|
try:
|
|
|
|
conn.set_vcpu_hotplug(eval(status))
|
|
|
|
except libvirtError as lib_err:
|
2020-03-16 13:59:45 +00:00
|
|
|
messages.error(request, lib_err)
|
2019-11-29 11:48:24 +00:00
|
|
|
messages.success(request, msg)
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#resize')
|
|
|
|
|
2015-03-18 13:48:29 +00:00
|
|
|
if 'set_autostart' in request.POST:
|
2015-03-27 09:53:13 +00:00
|
|
|
conn.set_autostart(1)
|
2015-03-18 13:48:29 +00:00
|
|
|
msg = _("Set autostart")
|
2015-05-18 19:00:30 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2019-01-15 12:55:05 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#boot_opt')
|
2015-03-18 13:48:29 +00:00
|
|
|
|
|
|
|
if 'unset_autostart' in request.POST:
|
2015-03-27 09:53:13 +00:00
|
|
|
conn.set_autostart(0)
|
2015-03-18 13:48:29 +00:00
|
|
|
msg = _("Unset autostart")
|
2015-05-18 19:00:30 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2019-01-15 12:55:05 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#boot_opt')
|
|
|
|
|
|
|
|
if 'set_bootmenu' in request.POST:
|
|
|
|
conn.set_bootmenu(1)
|
|
|
|
msg = _("Enable boot menu")
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#boot_opt')
|
|
|
|
|
|
|
|
if 'unset_bootmenu' in request.POST:
|
|
|
|
conn.set_bootmenu(0)
|
|
|
|
msg = _("Disable boot menu")
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#boot_opt')
|
|
|
|
|
|
|
|
if 'set_bootorder' in request.POST:
|
|
|
|
bootorder = request.POST.get('bootorder', '')
|
|
|
|
if bootorder:
|
|
|
|
order_list = {}
|
|
|
|
for idx, val in enumerate(bootorder.split(',')):
|
2019-09-10 06:45:49 +00:00
|
|
|
dev_type, dev = val.split(':', 1)
|
|
|
|
order_list[idx] = {"type": dev_type, "dev": dev}
|
2019-01-15 12:55:05 +00:00
|
|
|
conn.set_bootorder(order_list)
|
|
|
|
msg = _("Set boot order")
|
2019-01-24 05:41:45 +00:00
|
|
|
|
|
|
|
if not conn.get_status() == 5:
|
2019-11-20 05:37:59 +00:00
|
|
|
messages.success(request, _("Boot menu changes applied. " +
|
|
|
|
"But it will be activated after shutdown"))
|
2019-01-24 05:41:45 +00:00
|
|
|
else:
|
|
|
|
messages.success(request, _("Boot order changed successfully."))
|
2019-01-15 12:55:05 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#boot_opt')
|
2015-03-18 13:48:29 +00:00
|
|
|
|
|
|
|
if 'change_xml' in request.POST:
|
|
|
|
exit_xml = request.POST.get('inst_xml', '')
|
|
|
|
if exit_xml:
|
|
|
|
conn._defineXML(exit_xml)
|
2015-03-27 09:53:13 +00:00
|
|
|
msg = _("Edit XML")
|
2015-05-18 19:00:30 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2015-03-24 07:22:30 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#xmledit')
|
2015-03-18 13:48:29 +00:00
|
|
|
|
2019-04-09 09:19:31 +00:00
|
|
|
if request.user.is_superuser or request.user.is_staff or userinstance.is_vnc:
|
2015-03-18 13:48:29 +00:00
|
|
|
if 'set_console_passwd' in request.POST:
|
|
|
|
if request.POST.get('auto_pass', ''):
|
2016-05-08 10:24:43 +00:00
|
|
|
passwd = randomPasswd()
|
2015-03-18 13:48:29 +00:00
|
|
|
else:
|
|
|
|
passwd = request.POST.get('console_passwd', '')
|
|
|
|
clear = request.POST.get('clear_pass', False)
|
|
|
|
if clear:
|
|
|
|
passwd = ''
|
|
|
|
if not passwd and not clear:
|
|
|
|
msg = _("Enter the console password or select Generate")
|
|
|
|
error_messages.append(msg)
|
|
|
|
if not error_messages:
|
|
|
|
if not conn.set_console_passwd(passwd):
|
2019-11-20 05:37:59 +00:00
|
|
|
msg = _("Error setting console password. " +
|
|
|
|
"You should check that your instance have an graphic device.")
|
2015-03-18 13:48:29 +00:00
|
|
|
error_messages.append(msg)
|
|
|
|
else:
|
2015-03-27 09:53:13 +00:00
|
|
|
msg = _("Set VNC password")
|
2015-05-18 19:00:30 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2015-04-21 12:40:18 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#vncsettings')
|
2015-03-18 13:48:29 +00:00
|
|
|
|
|
|
|
if 'set_console_keymap' in request.POST:
|
|
|
|
keymap = request.POST.get('console_keymap', '')
|
|
|
|
clear = request.POST.get('clear_keymap', False)
|
|
|
|
if clear:
|
|
|
|
conn.set_console_keymap('')
|
|
|
|
else:
|
|
|
|
conn.set_console_keymap(keymap)
|
2015-03-27 09:53:13 +00:00
|
|
|
msg = _("Set VNC keymap")
|
2015-05-18 19:00:30 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2015-04-21 12:40:18 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#vncsettings')
|
2015-03-18 13:48:29 +00:00
|
|
|
|
|
|
|
if 'set_console_type' in request.POST:
|
|
|
|
console_type = request.POST.get('console_type', '')
|
2015-03-27 09:53:13 +00:00
|
|
|
msg = _("Set VNC type")
|
2020-05-28 21:43:26 +00:00
|
|
|
if console_type in console_types:
|
|
|
|
conn.set_console_type(console_type)
|
|
|
|
else:
|
|
|
|
msg = _("Console type not supported")
|
2015-05-18 19:00:30 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2015-04-21 12:40:18 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#vncsettings')
|
2018-09-28 10:33:21 +00:00
|
|
|
|
2018-06-15 12:13:50 +00:00
|
|
|
if 'set_console_listen_address' in request.POST:
|
|
|
|
console_type = request.POST.get('console_listen_address', '')
|
|
|
|
conn.set_console_listen_addr(console_type)
|
|
|
|
msg = _("Set VNC listen address")
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#vncsettings')
|
2015-03-18 13:48:29 +00:00
|
|
|
|
2016-05-09 10:08:31 +00:00
|
|
|
if request.user.is_superuser:
|
2019-12-24 14:19:11 +00:00
|
|
|
if 'set_guest_agent' in request.POST:
|
|
|
|
status = request.POST.get('guest_agent')
|
|
|
|
if status == 'True':
|
|
|
|
conn.add_guest_agent()
|
|
|
|
if status == 'False':
|
|
|
|
conn.remove_guest_agent()
|
|
|
|
|
2020-05-21 22:13:39 +00:00
|
|
|
msg = _(f"Set Quest Agent {status}")
|
2019-12-24 14:19:11 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#options')
|
|
|
|
|
2019-11-20 13:24:01 +00:00
|
|
|
if 'set_video_model' in request.POST:
|
|
|
|
video_model = request.POST.get('video_model', 'vga')
|
|
|
|
conn.set_video_model(video_model)
|
|
|
|
msg = _("Set Video Model")
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#options')
|
|
|
|
|
2015-03-18 13:48:29 +00:00
|
|
|
if 'migrate' in request.POST:
|
2019-12-19 13:06:51 +00:00
|
|
|
|
2015-03-18 13:48:29 +00:00
|
|
|
compute_id = request.POST.get('compute_id', '')
|
|
|
|
live = request.POST.get('live_migrate', False)
|
|
|
|
unsafe = request.POST.get('unsafe_migrate', False)
|
|
|
|
xml_del = request.POST.get('xml_delete', False)
|
2017-01-04 12:14:30 +00:00
|
|
|
offline = request.POST.get('offline_migrate', False)
|
2019-12-19 13:06:51 +00:00
|
|
|
autoconverge = request.POST.get('autoconverge', False)
|
|
|
|
compress = request.POST.get('compress', False)
|
|
|
|
postcopy = request.POST.get('postcopy', False)
|
2018-09-20 11:48:32 +00:00
|
|
|
|
2015-03-18 13:48:29 +00:00
|
|
|
new_compute = Compute.objects.get(id=compute_id)
|
2019-12-19 13:06:51 +00:00
|
|
|
try:
|
|
|
|
migrate_instance(new_compute, instance, live, unsafe, xml_del, offline)
|
|
|
|
return HttpResponseRedirect(reverse('instance', args=[new_compute.id, vname]))
|
|
|
|
except libvirtError as err:
|
|
|
|
messages.error(request, err)
|
|
|
|
addlogmsg(request.user.username, instance.name, err)
|
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#migrate')
|
2015-03-18 13:48:29 +00:00
|
|
|
|
2016-01-14 15:59:50 +00:00
|
|
|
if 'change_network' in request.POST:
|
2018-09-26 14:20:46 +00:00
|
|
|
msg = _("Change network")
|
2016-01-14 15:59:50 +00:00
|
|
|
network_data = {}
|
|
|
|
|
|
|
|
for post in request.POST:
|
2018-08-28 10:18:35 +00:00
|
|
|
if post.startswith('net-source-'):
|
|
|
|
(source, source_type) = get_network_tuple(request.POST.get(post))
|
|
|
|
network_data[post] = source
|
|
|
|
network_data[post + '-type'] = source_type
|
|
|
|
elif post.startswith('net-'):
|
2016-01-14 15:59:50 +00:00
|
|
|
network_data[post] = request.POST.get(post, '')
|
|
|
|
|
|
|
|
conn.change_network(network_data)
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
2019-07-17 10:52:14 +00:00
|
|
|
msg = _("Network Device Config is changed. Please shutdown instance to activate.")
|
2018-09-28 10:33:21 +00:00
|
|
|
if conn.get_status() != 5: messages.success(request, msg)
|
2016-01-14 15:59:50 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#network')
|
|
|
|
|
2018-08-28 08:55:27 +00:00
|
|
|
if 'add_network' in request.POST:
|
2018-09-26 14:20:46 +00:00
|
|
|
msg = _("Add network")
|
2018-08-28 08:55:27 +00:00
|
|
|
mac = request.POST.get('add-net-mac')
|
2018-09-26 14:20:46 +00:00
|
|
|
nwfilter = request.POST.get('add-net-nwfilter')
|
2018-08-28 10:18:35 +00:00
|
|
|
(source, source_type) = get_network_tuple(request.POST.get('add-net-network'))
|
2018-08-28 08:55:27 +00:00
|
|
|
|
2018-09-24 11:41:13 +00:00
|
|
|
conn.add_network(mac, source, source_type, nwfilter=nwfilter)
|
2018-08-28 08:55:27 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#network')
|
2018-09-26 14:20:46 +00:00
|
|
|
|
|
|
|
if 'delete_network' in request.POST:
|
|
|
|
msg = _("Delete network")
|
|
|
|
mac_address = request.POST.get('delete_network', '')
|
|
|
|
|
|
|
|
conn.delete_network(mac_address)
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#network')
|
|
|
|
|
2019-12-24 11:54:04 +00:00
|
|
|
if 'set_link_state' in request.POST:
|
|
|
|
mac_address = request.POST.get('mac', '')
|
|
|
|
state = request.POST.get('set_link_state')
|
|
|
|
state = 'down' if state == 'up' else 'up'
|
|
|
|
conn.set_link_state(mac_address, state)
|
2020-05-21 22:13:39 +00:00
|
|
|
msg = _(f"Set Link State: {state}")
|
2019-12-24 11:54:04 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#network')
|
|
|
|
|
2019-11-20 05:37:59 +00:00
|
|
|
if 'set_qos' in request.POST:
|
|
|
|
qos_dir = request.POST.get('qos_direction', '')
|
|
|
|
average = request.POST.get('qos_average') or 0
|
|
|
|
peak = request.POST.get('qos_peak') or 0
|
|
|
|
burst = request.POST.get('qos_burst') or 0
|
|
|
|
keys = request.POST.keys()
|
|
|
|
mac_key = [key for key in keys if 'mac' in key]
|
|
|
|
if mac_key: mac = request.POST.get(mac_key[0])
|
|
|
|
|
|
|
|
try:
|
|
|
|
conn.set_qos(mac, qos_dir, average, peak, burst)
|
|
|
|
if conn.get_status() == 5:
|
2020-05-21 22:13:39 +00:00
|
|
|
messages.success(request, _(f"{qos_dir.capitalize()} QoS is set"))
|
2019-11-20 05:37:59 +00:00
|
|
|
else:
|
|
|
|
messages.success(request,
|
2020-05-21 22:13:39 +00:00
|
|
|
_(f"{qos_dir.capitalize()} QoS is set. Network XML is changed.") +
|
|
|
|
_("Stop and start network to activate new config"))
|
2019-11-20 05:37:59 +00:00
|
|
|
|
|
|
|
except libvirtError as le:
|
2020-03-16 13:59:45 +00:00
|
|
|
messages.error(request, le)
|
2019-11-20 05:37:59 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#network')
|
|
|
|
if 'unset_qos' in request.POST:
|
|
|
|
qos_dir = request.POST.get('qos_direction', '')
|
|
|
|
mac = request.POST.get('net-mac')
|
|
|
|
conn.unset_qos(mac, qos_dir)
|
|
|
|
|
|
|
|
if conn.get_status() == 5:
|
2020-05-21 22:13:39 +00:00
|
|
|
messages.success(request, _(f"{qos_dir.capitalize()} QoS is deleted"))
|
2019-11-20 05:37:59 +00:00
|
|
|
else:
|
|
|
|
messages.success(request,
|
2020-05-21 22:13:39 +00:00
|
|
|
f"{qos_dir.capitalize()} QoS is deleted. Network XML is changed. " +
|
2019-11-20 05:37:59 +00:00
|
|
|
"Stop and start network to activate new config.")
|
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#network')
|
|
|
|
|
2017-09-15 10:40:37 +00:00
|
|
|
if 'add_owner' in request.POST:
|
|
|
|
user_id = int(request.POST.get('user_id', ''))
|
2018-09-28 10:33:21 +00:00
|
|
|
|
2020-05-28 21:43:26 +00:00
|
|
|
if appsettings.get(key="ALLOW_INSTANCE_MULTIPLE_OWNER").value == 'True':
|
2017-09-15 10:40:37 +00:00
|
|
|
check_inst = UserInstance.objects.filter(instance=instance, user_id=user_id)
|
|
|
|
else:
|
|
|
|
check_inst = UserInstance.objects.filter(instance=instance)
|
2018-09-28 10:33:21 +00:00
|
|
|
|
2017-09-15 10:40:37 +00:00
|
|
|
if check_inst:
|
2020-05-28 21:43:26 +00:00
|
|
|
msg = _("One owner is allowed and owner already added")
|
2017-09-15 10:40:37 +00:00
|
|
|
error_messages.append(msg)
|
|
|
|
else:
|
|
|
|
add_user_inst = UserInstance(instance=instance, user_id=user_id)
|
|
|
|
add_user_inst.save()
|
2020-05-21 22:13:39 +00:00
|
|
|
msg = _(f"Added owner {user_id}")
|
2017-09-15 10:40:37 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#users')
|
|
|
|
|
|
|
|
if 'del_owner' in request.POST:
|
|
|
|
userinstance_id = int(request.POST.get('userinstance', ''))
|
|
|
|
userinstance = UserInstance.objects.get(pk=userinstance_id)
|
|
|
|
userinstance.delete()
|
2020-05-21 22:13:39 +00:00
|
|
|
msg = _(f"Deleted owner {userinstance_id}")
|
2017-09-15 10:40:37 +00:00
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#users')
|
|
|
|
|
2016-03-23 08:00:42 +00:00
|
|
|
if request.user.is_superuser or request.user.userattributes.can_clone_instances:
|
|
|
|
if 'clone' in request.POST:
|
2019-03-19 11:39:34 +00:00
|
|
|
clone_data = dict()
|
2016-03-23 08:00:42 +00:00
|
|
|
clone_data['name'] = request.POST.get('name', '')
|
|
|
|
|
2018-09-28 10:33:21 +00:00
|
|
|
disk_sum = sum([disk['size'] >> 30 for disk in disks])
|
2016-03-31 11:12:52 +00:00
|
|
|
quota_msg = check_user_quota(1, vcpu, memory, disk_sum)
|
2016-03-23 11:04:15 +00:00
|
|
|
check_instance = Instance.objects.filter(name=clone_data['name'])
|
2018-09-28 10:33:21 +00:00
|
|
|
|
2020-05-28 21:43:26 +00:00
|
|
|
clone_data['disk_owner_uid'] = default_disk_owner_uid
|
|
|
|
clone_data['disk_owner_gid'] = default_disk_owner_gid
|
|
|
|
|
2017-06-15 09:57:31 +00:00
|
|
|
for post in request.POST:
|
|
|
|
clone_data[post] = request.POST.get(post, '').strip()
|
2018-09-28 10:33:21 +00:00
|
|
|
|
2020-05-28 21:43:26 +00:00
|
|
|
if clone_instance_auto_name == 'True' and not clone_data['name']:
|
2018-06-19 11:06:57 +00:00
|
|
|
auto_vname = clone_free_names[0]
|
|
|
|
clone_data['name'] = auto_vname
|
|
|
|
clone_data['clone-net-mac-0'] = _get_dhcp_mac_address(auto_vname)
|
2018-09-11 13:11:13 +00:00
|
|
|
for disk in disks:
|
|
|
|
disk_dev = "disk-{}".format(disk['dev'])
|
|
|
|
disk_name = get_clone_disk_name(disk, vname, auto_vname)
|
|
|
|
clone_data[disk_dev] = disk_name
|
2018-09-28 10:33:21 +00:00
|
|
|
|
2017-06-15 09:57:31 +00:00
|
|
|
if not request.user.is_superuser and quota_msg:
|
2020-05-19 16:53:54 +00:00
|
|
|
msg = _(f"User '{quota_msg}' quota reached, cannot create '{clone_data['name']}'!")
|
2016-03-23 08:00:42 +00:00
|
|
|
error_messages.append(msg)
|
2016-03-23 11:04:15 +00:00
|
|
|
elif check_instance:
|
2020-05-19 16:53:54 +00:00
|
|
|
msg = _(f"Instance '{clone_data['name']}' already exists!")
|
2016-03-23 08:00:42 +00:00
|
|
|
error_messages.append(msg)
|
2016-09-06 11:01:45 +00:00
|
|
|
elif not re.match(r'^[a-zA-Z0-9-]+$', clone_data['name']):
|
2020-05-19 16:53:54 +00:00
|
|
|
msg = _(f"Instance name '{clone_data['name']}' contains invalid characters!")
|
2016-09-06 11:01:45 +00:00
|
|
|
error_messages.append(msg)
|
2019-09-10 06:45:49 +00:00
|
|
|
elif not re.match(r'^([0-9A-F]{2})(:?[0-9A-F]{2}){5}$', clone_data['clone-net-mac-0'],
|
2018-09-28 10:33:21 +00:00
|
|
|
re.IGNORECASE):
|
2020-05-19 16:53:54 +00:00
|
|
|
msg = _(f"Instance MAC '{clone_data['clone-net-mac-0']}' invalid format!")
|
2017-06-15 09:57:31 +00:00
|
|
|
error_messages.append(msg)
|
2016-03-23 08:00:42 +00:00
|
|
|
else:
|
2018-10-24 13:19:30 +00:00
|
|
|
new_instance = Instance(compute_id=compute_id, name=clone_data['name'])
|
2020-03-16 13:59:45 +00:00
|
|
|
# new_instance.save()
|
2018-10-24 13:19:30 +00:00
|
|
|
try:
|
|
|
|
new_uuid = conn.clone_instance(clone_data)
|
|
|
|
new_instance.uuid = new_uuid
|
|
|
|
new_instance.save()
|
|
|
|
except Exception as e:
|
2020-03-16 13:59:45 +00:00
|
|
|
# new_instance.delete()
|
2018-10-24 13:19:30 +00:00
|
|
|
raise e
|
2019-12-19 10:49:41 +00:00
|
|
|
|
|
|
|
user_instance = UserInstance(instance_id=new_instance.id, user_id=request.user.id, is_delete=True)
|
|
|
|
user_instance.save()
|
2016-03-23 08:00:42 +00:00
|
|
|
|
|
|
|
msg = _("Clone of '%s'" % instance.name)
|
|
|
|
addlogmsg(request.user.username, new_instance.name, msg)
|
2020-05-28 21:43:26 +00:00
|
|
|
|
|
|
|
if appsettings.get(key="CLONE_INSTANCE_AUTO_MIGRATE").value == 'True':
|
2018-09-20 11:48:32 +00:00
|
|
|
new_compute = Compute.objects.order_by('?').first()
|
|
|
|
migrate_instance(new_compute, new_instance, xml_del=True, offline=True)
|
2018-09-28 10:33:21 +00:00
|
|
|
return HttpResponseRedirect(
|
|
|
|
reverse('instance', args=[new_instance.compute.id, new_instance.name]))
|
2016-03-23 08:00:42 +00:00
|
|
|
|
2018-10-24 13:42:00 +00:00
|
|
|
if 'change_options' in request.POST and (request.user.is_superuser or request.user.is_staff or userinstance.is_change):
|
2017-10-26 13:51:10 +00:00
|
|
|
instance.is_template = request.POST.get('is_template', False)
|
|
|
|
instance.save()
|
2018-09-28 10:33:21 +00:00
|
|
|
|
2017-10-26 13:51:10 +00:00
|
|
|
options = {}
|
|
|
|
for post in request.POST:
|
|
|
|
if post in ['title', 'description']:
|
|
|
|
options[post] = request.POST.get(post, '')
|
|
|
|
conn.set_options(options)
|
2018-09-28 10:33:21 +00:00
|
|
|
|
2017-10-26 13:51:10 +00:00
|
|
|
msg = _("Edit options")
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
return HttpResponseRedirect(request.get_full_path() + '#options')
|
2015-03-12 14:15:36 +00:00
|
|
|
conn.close()
|
|
|
|
|
2015-03-16 09:57:55 +00:00
|
|
|
except libvirtError as lib_err:
|
2020-03-16 13:59:45 +00:00
|
|
|
error_messages.append(lib_err)
|
|
|
|
addlogmsg(request.user.username, vname, lib_err)
|
2015-03-12 14:15:36 +00:00
|
|
|
|
2015-04-02 13:20:46 +00:00
|
|
|
return render(request, 'instance.html', locals())
|
2015-03-20 10:06:32 +00:00
|
|
|
|
|
|
|
|
2015-04-02 12:39:40 +00:00
|
|
|
def inst_status(request, compute_id, vname):
|
2015-03-23 12:28:24 +00:00
|
|
|
"""
|
|
|
|
:param request:
|
2019-09-10 13:05:23 +00:00
|
|
|
:param compute_id:
|
|
|
|
:param vname:
|
2015-03-23 12:28:24 +00:00
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
|
2015-04-02 12:39:40 +00:00
|
|
|
compute = get_object_or_404(Compute, pk=compute_id)
|
2015-03-24 12:45:38 +00:00
|
|
|
response = HttpResponse()
|
|
|
|
response['Content-Type'] = "text/javascript"
|
2015-03-23 12:28:24 +00:00
|
|
|
|
|
|
|
try:
|
|
|
|
conn = wvmInstance(compute.hostname,
|
|
|
|
compute.login,
|
|
|
|
compute.password,
|
|
|
|
compute.type,
|
|
|
|
vname)
|
2015-03-24 12:45:38 +00:00
|
|
|
data = json.dumps({'status': conn.get_status()})
|
2015-03-23 12:28:24 +00:00
|
|
|
conn.close()
|
|
|
|
except libvirtError:
|
2015-03-24 12:45:38 +00:00
|
|
|
data = json.dumps({'error': 'Error 500'})
|
2015-03-23 12:28:24 +00:00
|
|
|
response.write(data)
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
2019-01-17 07:38:53 +00:00
|
|
|
def get_host_instances(request, comp):
|
2018-09-28 10:33:21 +00:00
|
|
|
|
|
|
|
def refresh_instance_database(comp, inst_name, info):
|
|
|
|
def get_userinstances_info(instance):
|
|
|
|
info = {}
|
|
|
|
uis = UserInstance.objects.filter(instance=instance)
|
|
|
|
info['count'] = uis.count()
|
|
|
|
if info['count'] > 0:
|
|
|
|
info['first_user'] = uis[0]
|
|
|
|
else:
|
|
|
|
info['first_user'] = None
|
|
|
|
return info
|
|
|
|
|
2019-02-07 08:09:56 +00:00
|
|
|
# Multiple Instance Name Check
|
2018-09-28 10:33:21 +00:00
|
|
|
instances = Instance.objects.filter(name=inst_name)
|
|
|
|
if instances.count() > 1:
|
|
|
|
for i in instances:
|
|
|
|
user_instances_count = UserInstance.objects.filter(instance=i).count()
|
|
|
|
if user_instances_count == 0:
|
2019-02-07 08:09:56 +00:00
|
|
|
addlogmsg(request.user.username, i.name, _("Deleting due to multiple(Instance Name) records."))
|
|
|
|
i.delete()
|
|
|
|
|
|
|
|
# Multiple UUID Check
|
|
|
|
instances = Instance.objects.filter(uuid=info['uuid'])
|
|
|
|
if instances.count() > 1:
|
|
|
|
for i in instances:
|
|
|
|
if i.name != inst_name:
|
|
|
|
addlogmsg(request.user.username, i.name, _("Deleting due to multiple(UUID) records."))
|
2018-09-28 10:33:21 +00:00
|
|
|
i.delete()
|
|
|
|
|
|
|
|
try:
|
|
|
|
inst_on_db = Instance.objects.get(compute_id=comp["id"], name=inst_name)
|
|
|
|
if inst_on_db.uuid != info['uuid']:
|
|
|
|
inst_on_db.save()
|
|
|
|
|
|
|
|
all_host_vms[comp["id"],
|
2019-09-10 06:45:49 +00:00
|
|
|
comp["name"],
|
|
|
|
comp["status"],
|
|
|
|
comp["cpu"],
|
|
|
|
comp["mem_size"],
|
|
|
|
comp["mem_perc"]][inst_name]['is_template'] = inst_on_db.is_template
|
2018-09-28 10:33:21 +00:00
|
|
|
all_host_vms[comp["id"],
|
2019-09-10 06:45:49 +00:00
|
|
|
comp["name"],
|
|
|
|
comp["status"],
|
|
|
|
comp["cpu"],
|
|
|
|
comp["mem_size"],
|
|
|
|
comp["mem_perc"]][inst_name]['userinstances'] = get_userinstances_info(inst_on_db)
|
2018-09-28 10:33:21 +00:00
|
|
|
except Instance.DoesNotExist:
|
|
|
|
inst_on_db = Instance(compute_id=comp["id"], name=inst_name, uuid=info['uuid'])
|
|
|
|
inst_on_db.save()
|
|
|
|
|
2019-11-29 11:48:24 +00:00
|
|
|
all_host_vms = OrderedDict()
|
2018-09-28 10:33:21 +00:00
|
|
|
status = connection_manager.host_is_up(comp.type, comp.hostname)
|
|
|
|
|
2019-07-03 14:49:22 +00:00
|
|
|
if status is True:
|
2020-03-16 13:59:45 +00:00
|
|
|
conn = wvmHostDetails(comp.hostname, comp.login, comp.password, comp.type)
|
2018-09-28 10:33:21 +00:00
|
|
|
comp_node_info = conn.get_node_info()
|
|
|
|
comp_mem = conn.get_memory_usage()
|
|
|
|
comp_instances = conn.get_host_instances(True)
|
|
|
|
|
|
|
|
if comp_instances:
|
|
|
|
comp_info = {
|
|
|
|
"id": comp.id,
|
|
|
|
"name": comp.name,
|
|
|
|
"status": status,
|
|
|
|
"cpu": comp_node_info[3],
|
|
|
|
"mem_size": comp_node_info[2],
|
|
|
|
"mem_perc": comp_mem['percent']
|
|
|
|
}
|
|
|
|
all_host_vms[comp_info["id"], comp_info["name"], comp_info["status"], comp_info["cpu"],
|
|
|
|
comp_info["mem_size"], comp_info["mem_perc"]] = comp_instances
|
|
|
|
for vm, info in comp_instances.items():
|
|
|
|
refresh_instance_database(comp_info, vm, info)
|
|
|
|
|
|
|
|
conn.close()
|
2019-07-03 14:49:22 +00:00
|
|
|
else:
|
2020-05-19 16:53:54 +00:00
|
|
|
raise libvirtError("Problem occurred with host: {} - {}".format(comp.name, status))
|
2018-09-28 10:33:21 +00:00
|
|
|
return all_host_vms
|
|
|
|
|
2019-01-17 07:38:53 +00:00
|
|
|
|
2018-09-28 10:33:21 +00:00
|
|
|
def get_user_instances(request):
|
|
|
|
all_user_vms = {}
|
|
|
|
user_instances = UserInstance.objects.filter(user_id=request.user.id)
|
|
|
|
for usr_inst in user_instances:
|
|
|
|
if connection_manager.host_is_up(usr_inst.instance.compute.type,
|
|
|
|
usr_inst.instance.compute.hostname):
|
2020-04-06 10:05:20 +00:00
|
|
|
conn = wvmHostDetails(usr_inst.instance.compute.hostname,
|
2018-09-28 10:33:21 +00:00
|
|
|
usr_inst.instance.compute.login,
|
|
|
|
usr_inst.instance.compute.password,
|
|
|
|
usr_inst.instance.compute.type)
|
|
|
|
all_user_vms[usr_inst] = conn.get_user_instances(usr_inst.instance.name)
|
|
|
|
all_user_vms[usr_inst].update({'compute_id': usr_inst.instance.compute.id})
|
|
|
|
return all_user_vms
|
|
|
|
|
|
|
|
|
|
|
|
def instances_actions(request):
|
|
|
|
name = request.POST.get('name', '')
|
|
|
|
compute_id = request.POST.get('compute_id', '')
|
|
|
|
instance = Instance.objects.get(compute_id=compute_id, name=name)
|
|
|
|
|
|
|
|
conn = wvmInstances(instance.compute.hostname,
|
|
|
|
instance.compute.login,
|
|
|
|
instance.compute.password,
|
|
|
|
instance.compute.type)
|
|
|
|
if 'poweron' in request.POST:
|
2018-10-24 13:56:05 +00:00
|
|
|
if instance.is_template:
|
|
|
|
msg = _("Templates cannot be started.")
|
|
|
|
messages.error(request, msg)
|
|
|
|
else:
|
|
|
|
msg = _("Power On")
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
conn.start(name)
|
|
|
|
return HttpResponseRedirect(request.get_full_path())
|
2018-09-28 10:33:21 +00:00
|
|
|
|
|
|
|
if 'poweroff' in request.POST:
|
|
|
|
msg = _("Power Off")
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
conn.shutdown(name)
|
|
|
|
return HttpResponseRedirect(request.get_full_path())
|
|
|
|
|
2019-07-31 06:59:44 +00:00
|
|
|
if 'powerforce' in request.POST:
|
2019-09-10 06:45:49 +00:00
|
|
|
conn.force_shutdown(name)
|
2019-07-31 06:59:44 +00:00
|
|
|
msg = _("Force Off")
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
return HttpResponseRedirect(request.get_full_path())
|
|
|
|
|
2018-09-28 10:33:21 +00:00
|
|
|
if 'powercycle' in request.POST:
|
|
|
|
msg = _("Power Cycle")
|
|
|
|
conn.force_shutdown(name)
|
|
|
|
conn.start(name)
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
return HttpResponseRedirect(request.get_full_path())
|
|
|
|
|
|
|
|
if 'getvvfile' in request.POST:
|
|
|
|
msg = _("Send console.vv file")
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
response = HttpResponse(content='', content_type='application/x-virt-viewer', status=200, reason=None,
|
|
|
|
charset='utf-8')
|
|
|
|
response.writelines('[virt-viewer]\n')
|
|
|
|
response.writelines('type=' + conn.graphics_type(name) + '\n')
|
|
|
|
response.writelines('host=' + conn.graphics_listen(name) + '\n')
|
|
|
|
response.writelines('port=' + conn.graphics_port(name) + '\n')
|
|
|
|
response.writelines('title=' + conn.domain_name(name) + '\n')
|
|
|
|
response.writelines('password=' + conn.graphics_passwd(name) + '\n')
|
|
|
|
response.writelines('enable-usbredir=1\n')
|
|
|
|
response.writelines('disable-effects=all\n')
|
|
|
|
response.writelines('secure-attention=ctrl+alt+ins\n')
|
|
|
|
response.writelines('release-cursor=ctrl+alt\n')
|
|
|
|
response.writelines('fullscreen=1\n')
|
|
|
|
response.writelines('delete-this-file=1\n')
|
|
|
|
response['Content-Disposition'] = 'attachment; filename="console.vv"'
|
|
|
|
return response
|
|
|
|
|
|
|
|
if request.user.is_superuser:
|
|
|
|
if 'suspend' in request.POST:
|
|
|
|
msg = _("Suspend")
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
conn.suspend(name)
|
|
|
|
return HttpResponseRedirect(request.get_full_path())
|
|
|
|
|
|
|
|
if 'resume' in request.POST:
|
|
|
|
msg = _("Resume")
|
|
|
|
addlogmsg(request.user.username, instance.name, msg)
|
|
|
|
conn.resume(name)
|
|
|
|
return HttpResponseRedirect(request.get_full_path())
|
2019-09-11 08:51:20 +00:00
|
|
|
return HttpResponseRedirect(request.get_full_path())
|
2018-09-28 10:33:21 +00:00
|
|
|
|
2019-10-30 08:05:50 +00:00
|
|
|
|
2015-03-20 10:06:32 +00:00
|
|
|
def inst_graph(request, compute_id, vname):
|
|
|
|
"""
|
2015-03-23 12:28:24 +00:00
|
|
|
:param request:
|
2019-10-30 08:05:50 +00:00
|
|
|
:param compute_id:
|
|
|
|
:param vname:
|
2015-03-23 12:28:24 +00:00
|
|
|
:return:
|
2015-03-20 10:06:32 +00:00
|
|
|
"""
|
|
|
|
json_blk = []
|
|
|
|
json_net = []
|
2019-05-21 06:12:28 +00:00
|
|
|
|
2015-04-02 12:39:40 +00:00
|
|
|
compute = get_object_or_404(Compute, pk=compute_id)
|
2015-03-23 12:28:24 +00:00
|
|
|
response = HttpResponse()
|
|
|
|
response['Content-Type'] = "text/javascript"
|
|
|
|
|
2015-03-20 10:06:32 +00:00
|
|
|
try:
|
|
|
|
conn = wvmInstance(compute.hostname,
|
|
|
|
compute.login,
|
|
|
|
compute.password,
|
|
|
|
compute.type,
|
|
|
|
vname)
|
|
|
|
cpu_usage = conn.cpu_usage()
|
2019-05-21 06:12:28 +00:00
|
|
|
mem_usage = conn.mem_usage()
|
2015-03-20 10:06:32 +00:00
|
|
|
blk_usage = conn.disk_usage()
|
|
|
|
net_usage = conn.net_usage()
|
|
|
|
conn.close()
|
|
|
|
|
2019-05-21 06:12:28 +00:00
|
|
|
current_time = time.strftime("%H:%M:%S")
|
2015-03-20 10:06:32 +00:00
|
|
|
for blk in blk_usage:
|
2019-05-21 06:12:28 +00:00
|
|
|
json_blk.append({'dev': blk['dev'], 'data': [int(blk['rd']) / 1048576, int(blk['wr']) / 1048576]})
|
2015-03-20 10:06:32 +00:00
|
|
|
|
|
|
|
for net in net_usage:
|
2019-05-21 06:12:28 +00:00
|
|
|
json_net.append({'dev': net['dev'], 'data': [int(net['rx']) / 1048576, int(net['tx']) / 1048576]})
|
2015-03-20 10:06:32 +00:00
|
|
|
|
2019-05-21 06:12:28 +00:00
|
|
|
data = json.dumps({'cpudata': int(cpu_usage['cpu']),
|
|
|
|
'memdata': mem_usage,
|
|
|
|
'blkdata': json_blk,
|
|
|
|
'netdata': json_net,
|
|
|
|
'timeline': current_time})
|
2015-03-20 10:06:32 +00:00
|
|
|
|
2015-03-23 12:28:24 +00:00
|
|
|
except libvirtError:
|
|
|
|
data = json.dumps({'error': 'Error 500'})
|
|
|
|
|
2015-03-20 10:06:32 +00:00
|
|
|
response.write(data)
|
2015-03-24 07:22:30 +00:00
|
|
|
return response
|
2016-02-08 11:28:52 +00:00
|
|
|
|
2018-07-26 12:29:56 +00:00
|
|
|
|
2018-06-19 11:06:57 +00:00
|
|
|
def _get_dhcp_mac_address(vname):
|
2019-12-19 13:06:51 +00:00
|
|
|
|
|
|
|
dhcp_file = settings.BASE_DIR + '/dhcpd.conf'
|
2018-07-26 09:35:37 +00:00
|
|
|
mac = ''
|
2016-02-11 13:48:41 +00:00
|
|
|
if os.path.isfile(dhcp_file):
|
|
|
|
with open(dhcp_file, 'r') as f:
|
|
|
|
name_found = False
|
|
|
|
for line in f:
|
|
|
|
if "host %s." % vname in line:
|
|
|
|
name_found = True
|
|
|
|
if name_found and "hardware ethernet" in line:
|
2018-06-19 11:06:57 +00:00
|
|
|
mac = line.split(' ')[-1].strip().strip(';')
|
2016-02-11 13:48:41 +00:00
|
|
|
break
|
2018-06-19 11:06:57 +00:00
|
|
|
return mac
|
|
|
|
|
2018-07-26 12:29:56 +00:00
|
|
|
|
2018-06-19 11:06:57 +00:00
|
|
|
def guess_mac_address(request, vname):
|
2018-10-24 09:04:05 +00:00
|
|
|
data = {'vname': vname}
|
2018-07-26 09:35:37 +00:00
|
|
|
mac = _get_dhcp_mac_address(vname)
|
|
|
|
if not mac:
|
|
|
|
mac = _get_random_mac_address()
|
|
|
|
data['mac'] = mac
|
|
|
|
return HttpResponse(json.dumps(data))
|
|
|
|
|
2018-07-26 12:29:56 +00:00
|
|
|
|
2018-07-26 09:35:37 +00:00
|
|
|
def _get_random_mac_address():
|
|
|
|
mac = '52:54:00:%02x:%02x:%02x' % (
|
|
|
|
random.randint(0x00, 0xff),
|
|
|
|
random.randint(0x00, 0xff),
|
|
|
|
random.randint(0x00, 0xff)
|
|
|
|
)
|
|
|
|
return mac
|
|
|
|
|
2018-07-26 12:29:56 +00:00
|
|
|
|
2018-07-26 09:35:37 +00:00
|
|
|
def random_mac_address(request):
|
2019-01-17 07:38:53 +00:00
|
|
|
data = dict()
|
2018-07-26 09:35:37 +00:00
|
|
|
data['mac'] = _get_random_mac_address()
|
2017-05-11 08:46:39 +00:00
|
|
|
return HttpResponse(json.dumps(data))
|
2016-02-11 13:37:26 +00:00
|
|
|
|
2018-07-26 12:29:56 +00:00
|
|
|
|
2016-05-27 12:13:24 +00:00
|
|
|
def guess_clone_name(request):
|
|
|
|
dhcp_file = '/srv/webvirtcloud/dhcpd.conf'
|
2020-05-28 21:43:26 +00:00
|
|
|
prefix = appsettings.get(key="CLONE_INSTANCE_DEFAULT_PREFIX").value
|
2016-05-27 12:13:24 +00:00
|
|
|
if os.path.isfile(dhcp_file):
|
|
|
|
instance_names = [i.name for i in Instance.objects.filter(name__startswith=prefix)]
|
|
|
|
with open(dhcp_file, 'r') as f:
|
|
|
|
for line in f:
|
|
|
|
line = line.strip()
|
|
|
|
if "host %s" % prefix in line:
|
2016-06-08 11:37:26 +00:00
|
|
|
fqdn = line.split(' ')[1]
|
|
|
|
hostname = fqdn.split('.')[0]
|
2016-05-27 12:13:24 +00:00
|
|
|
if hostname.startswith(prefix) and hostname not in instance_names:
|
|
|
|
return HttpResponse(json.dumps({'name': hostname}))
|
2017-05-11 08:46:39 +00:00
|
|
|
return HttpResponse(json.dumps({}))
|
2016-05-27 12:13:24 +00:00
|
|
|
|
2018-07-26 12:29:56 +00:00
|
|
|
|
2016-02-11 13:37:26 +00:00
|
|
|
def check_instance(request, vname):
|
2019-01-17 07:38:53 +00:00
|
|
|
instance = Instance.objects.filter(name=vname)
|
2018-10-24 09:04:05 +00:00
|
|
|
data = {'vname': vname, 'exists': False}
|
2019-01-17 07:38:53 +00:00
|
|
|
if instance:
|
2016-02-11 13:37:26 +00:00
|
|
|
data['exists'] = True
|
2017-05-11 08:46:39 +00:00
|
|
|
return HttpResponse(json.dumps(data))
|
|
|
|
|
2018-07-30 10:33:09 +00:00
|
|
|
|
2018-09-11 13:11:13 +00:00
|
|
|
def get_clone_disk_name(disk, prefix, clone_name=''):
|
|
|
|
if not disk['image']:
|
|
|
|
return None
|
|
|
|
if disk['image'].startswith(prefix) and clone_name:
|
|
|
|
suffix = disk['image'][len(prefix):]
|
|
|
|
image = "{}{}".format(clone_name, suffix)
|
|
|
|
elif "." in disk['image'] and len(disk['image'].rsplit(".", 1)[1]) <= 7:
|
|
|
|
name, suffix = disk['image'].rsplit(".", 1)
|
|
|
|
image = "{}-clone.{}".format(name, suffix)
|
|
|
|
else:
|
|
|
|
image = "{}-clone".format(disk['image'])
|
|
|
|
return image
|
|
|
|
|
2018-10-24 09:04:05 +00:00
|
|
|
|
2018-09-11 13:11:13 +00:00
|
|
|
def _get_clone_disks(disks, vname=''):
|
|
|
|
clone_disks = []
|
|
|
|
for disk in disks:
|
|
|
|
new_image = get_clone_disk_name(disk, vname)
|
|
|
|
if not new_image:
|
|
|
|
continue
|
|
|
|
new_disk = {
|
|
|
|
'dev': disk['dev'],
|
|
|
|
'storage': disk['storage'],
|
|
|
|
'image': new_image,
|
|
|
|
'format': disk['format']
|
|
|
|
}
|
|
|
|
clone_disks.append(new_disk)
|
|
|
|
return clone_disks
|
|
|
|
|
2018-10-24 09:04:05 +00:00
|
|
|
|
2017-05-11 08:46:39 +00:00
|
|
|
def sshkeys(request, vname):
|
|
|
|
"""
|
|
|
|
:param request:
|
2019-09-10 06:45:49 +00:00
|
|
|
:param vname:
|
2017-05-11 08:46:39 +00:00
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
|
|
|
|
instance_keys = []
|
|
|
|
userinstances = UserInstance.objects.filter(instance__name=vname)
|
2020-04-06 10:05:20 +00:00
|
|
|
|
2017-05-11 08:46:39 +00:00
|
|
|
for ui in userinstances:
|
|
|
|
keys = UserSSHKey.objects.filter(user=ui.user)
|
|
|
|
for k in keys:
|
|
|
|
instance_keys.append(k.keypublic)
|
2018-04-05 14:26:17 +00:00
|
|
|
if request.GET.get('plain', ''):
|
|
|
|
response = '\n'.join(instance_keys)
|
|
|
|
response += '\n'
|
|
|
|
else:
|
|
|
|
response = json.dumps(instance_keys)
|
|
|
|
return HttpResponse(response)
|
2018-03-13 12:56:58 +00:00
|
|
|
|
2018-07-30 10:33:09 +00:00
|
|
|
|
2020-05-19 16:53:54 +00:00
|
|
|
def get_hosts_status(computes):
|
|
|
|
"""
|
|
|
|
Function return all hosts all vds on host
|
|
|
|
"""
|
|
|
|
compute_data = []
|
|
|
|
for compute in computes:
|
|
|
|
compute_data.append({'id': compute.id,
|
|
|
|
'name': compute.name,
|
|
|
|
'hostname': compute.hostname,
|
|
|
|
'status': connection_manager.host_is_up(compute.type, compute.hostname),
|
|
|
|
'type': compute.type,
|
|
|
|
'login': compute.login,
|
|
|
|
'password': compute.password,
|
|
|
|
'details': compute.details
|
|
|
|
})
|
|
|
|
return compute_data
|
|
|
|
|
|
|
|
|
2018-03-13 12:56:58 +00:00
|
|
|
def delete_instance(instance, delete_disk=False):
|
|
|
|
compute = instance.compute
|
|
|
|
instance_name = instance.name
|
|
|
|
try:
|
|
|
|
conn = wvmInstance(compute.hostname,
|
|
|
|
compute.login,
|
|
|
|
compute.password,
|
|
|
|
compute.type,
|
|
|
|
instance.name)
|
|
|
|
|
|
|
|
del_userinstance = UserInstance.objects.filter(instance=instance)
|
|
|
|
if del_userinstance:
|
|
|
|
print("Deleting UserInstances")
|
|
|
|
print(del_userinstance)
|
|
|
|
del_userinstance.delete()
|
|
|
|
|
|
|
|
if conn.get_status() == 1:
|
|
|
|
print("Forcing shutdown")
|
|
|
|
conn.force_shutdown()
|
|
|
|
if delete_disk:
|
2019-09-10 06:45:49 +00:00
|
|
|
snapshots = sorted(conn.get_snapshot(), reverse=True, key=lambda k: k['date'])
|
2018-03-13 12:56:58 +00:00
|
|
|
for snap in snapshots:
|
|
|
|
print("Deleting snapshot {}".format(snap['name']))
|
|
|
|
conn.snapshot_delete(snap['name'])
|
|
|
|
print("Deleting disks")
|
2018-10-19 13:14:33 +00:00
|
|
|
conn.delete_all_disks()
|
2018-03-13 12:56:58 +00:00
|
|
|
|
|
|
|
conn.delete()
|
|
|
|
instance.delete()
|
|
|
|
|
2019-10-30 08:05:50 +00:00
|
|
|
print("Instance {} on compute {} successfully deleted".format(instance_name, compute.hostname))
|
2018-03-13 12:56:58 +00:00
|
|
|
|
|
|
|
except libvirtError as lib_err:
|
|
|
|
print("Error removing instance {} on compute {}".format(instance_name, compute.hostname))
|
|
|
|
raise lib_err
|