mirror of
https://github.com/retspen/webvirtcloud
synced 2024-11-01 03:54:15 +00:00
Bundle: Add/Delete Cdrom function added. Add disk device type/bus choice for custom instance creation. Change some cosmetics on create instance. Change some functions signature for compatibility. Add getting disk device types function. Fixed some bugs
This commit is contained in:
parent
469cc0560c
commit
eb8aae957e
7 changed files with 192 additions and 86 deletions
|
@ -4,7 +4,7 @@ from networks.views import networks, network
|
||||||
from secrets.views import secrets
|
from secrets.views import secrets
|
||||||
from create.views import create_instance
|
from create.views import create_instance
|
||||||
from interfaces.views import interfaces, interface
|
from interfaces.views import interfaces, interface
|
||||||
from computes.views import overview, compute_graph, computes
|
from computes.views import overview, compute_graph, computes, get_compute_disk_buses
|
||||||
from instances.views import instances
|
from instances.views import instances
|
||||||
from nwfilters.views import nwfilter, nwfilters
|
from nwfilters.views import nwfilter, nwfilters
|
||||||
|
|
||||||
|
@ -24,4 +24,5 @@ urlpatterns = [
|
||||||
url(r'^(?P<compute_id>[0-9]+)/nwfilter/(?P<nwfltr>[\w\-\.\:]+)/$', nwfilter, name='nwfilter'),
|
url(r'^(?P<compute_id>[0-9]+)/nwfilter/(?P<nwfltr>[\w\-\.\:]+)/$', nwfilter, name='nwfilter'),
|
||||||
url(r'^(?P<compute_id>[0-9]+)/secrets/$', secrets, name='secrets'),
|
url(r'^(?P<compute_id>[0-9]+)/secrets/$', secrets, name='secrets'),
|
||||||
url(r'^(?P<compute_id>[0-9]+)/create/$', create_instance, name='create_instance'),
|
url(r'^(?P<compute_id>[0-9]+)/create/$', create_instance, name='create_instance'),
|
||||||
|
url(r'^(?P<compute_id>[0-9]+)/disk/(?P<disk>[\w\-\.\/]+)/buses$', get_compute_disk_buses, name='buses'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -9,7 +9,7 @@ from instances.models import Instance
|
||||||
from accounts.models import UserInstance
|
from accounts.models import UserInstance
|
||||||
from computes.forms import ComputeAddTcpForm, ComputeAddSshForm, ComputeEditHostForm, ComputeAddTlsForm, ComputeAddSocketForm
|
from computes.forms import ComputeAddTcpForm, ComputeAddSshForm, ComputeEditHostForm, ComputeAddTlsForm, ComputeAddSocketForm
|
||||||
from vrtManager.hostdetails import wvmHostDetails
|
from vrtManager.hostdetails import wvmHostDetails
|
||||||
from vrtManager.connection import CONN_SSH, CONN_TCP, CONN_TLS, CONN_SOCKET, connection_manager
|
from vrtManager.connection import CONN_SSH, CONN_TCP, CONN_TLS, CONN_SOCKET, connection_manager, wvmConnect
|
||||||
from libvirt import libvirtError
|
from libvirt import libvirtError
|
||||||
|
|
||||||
|
|
||||||
|
@ -225,3 +225,32 @@ def compute_graph(request, compute_id):
|
||||||
response.cookies['mem'] = datasets['mem']
|
response.cookies['mem'] = datasets['mem']
|
||||||
response.write(data)
|
response.write(data)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def get_compute_disk_buses(request, compute_id, disk):
|
||||||
|
data = {}
|
||||||
|
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()
|
||||||
|
disk_bus_types = conn.get_disk_bus_types()
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,11 @@ from vrtManager import util
|
||||||
from libvirt import libvirtError
|
from libvirt import libvirtError
|
||||||
from webvirtcloud.settings import QEMU_CONSOLE_LISTEN_ADDRESSES
|
from webvirtcloud.settings import QEMU_CONSOLE_LISTEN_ADDRESSES
|
||||||
from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_CACHE
|
from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_CACHE
|
||||||
|
from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_BUS
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from logs.views import addlogmsg
|
from logs.views import addlogmsg
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def create_instance(request, compute_id):
|
def create_instance(request, compute_id):
|
||||||
"""
|
"""
|
||||||
|
@ -48,6 +50,9 @@ def create_instance(request, compute_id):
|
||||||
default_cache = INSTANCE_VOLUME_DEFAULT_CACHE
|
default_cache = INSTANCE_VOLUME_DEFAULT_CACHE
|
||||||
listener_addr = QEMU_CONSOLE_LISTEN_ADDRESSES
|
listener_addr = QEMU_CONSOLE_LISTEN_ADDRESSES
|
||||||
mac_auto = util.randomMAC()
|
mac_auto = util.randomMAC()
|
||||||
|
disk_devices = conn.get_disk_device_types()
|
||||||
|
disk_buses = conn.get_disk_bus_types()
|
||||||
|
default_bus = INSTANCE_VOLUME_DEFAULT_BUS
|
||||||
#get_images = sorted(conn.get_storages_images())
|
#get_images = sorted(conn.get_storages_images())
|
||||||
except libvirtError as lib_err:
|
except libvirtError as lib_err:
|
||||||
error_messages.append(lib_err)
|
error_messages.append(lib_err)
|
||||||
|
@ -92,7 +97,9 @@ def create_instance(request, compute_id):
|
||||||
except libvirtError as lib_err:
|
except libvirtError as lib_err:
|
||||||
error_messages.append(lib_err.message)
|
error_messages.append(lib_err.message)
|
||||||
if 'create' in request.POST:
|
if 'create' in request.POST:
|
||||||
volumes = {}
|
volume_list = []
|
||||||
|
|
||||||
|
clone_path = ""
|
||||||
form = NewVMForm(request.POST)
|
form = NewVMForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
data = form.cleaned_data
|
data = form.cleaned_data
|
||||||
|
@ -113,7 +120,13 @@ def create_instance(request, compute_id):
|
||||||
try:
|
try:
|
||||||
path = conn.create_volume(data['storage'], data['name'], data['hdd_size'],
|
path = conn.create_volume(data['storage'], data['name'], data['hdd_size'],
|
||||||
metadata=meta_prealloc)
|
metadata=meta_prealloc)
|
||||||
volumes[path] = conn.get_volume_type(path)
|
volume = dict()
|
||||||
|
volume['path'] = path
|
||||||
|
volume['type'] = conn.get_volume_type(path)
|
||||||
|
volume['device'] = 'disk'
|
||||||
|
volume['bus'] = 'virtio'
|
||||||
|
volume_list.append(volume)
|
||||||
|
#volumes[path] = conn.get_volume_type(path)
|
||||||
except libvirtError as lib_err:
|
except libvirtError as lib_err:
|
||||||
error_messages.append(lib_err.message)
|
error_messages.append(lib_err.message)
|
||||||
elif data['template']:
|
elif data['template']:
|
||||||
|
@ -124,16 +137,31 @@ def create_instance(request, compute_id):
|
||||||
error_messages.append(error_msg)
|
error_messages.append(error_msg)
|
||||||
else:
|
else:
|
||||||
clone_path = conn.clone_from_template(data['name'], templ_path, metadata=meta_prealloc)
|
clone_path = conn.clone_from_template(data['name'], templ_path, metadata=meta_prealloc)
|
||||||
volumes[clone_path] = conn.get_volume_type(clone_path)
|
volume = dict()
|
||||||
|
volume['path'] = clone_path
|
||||||
|
volume['type'] = conn.get_volume_type(clone_path)
|
||||||
|
volume['device'] = 'disk'
|
||||||
|
volume['bus'] = 'virtio'
|
||||||
|
volume_list.append(volume)
|
||||||
|
#volumes[clone_path] = conn.get_volume_type(clone_path)
|
||||||
else:
|
else:
|
||||||
if not data['images']:
|
if not data['images']:
|
||||||
error_msg = _("First you need to create or select an image")
|
error_msg = _("First you need to create or select an image")
|
||||||
error_messages.append(error_msg)
|
error_messages.append(error_msg)
|
||||||
else:
|
else:
|
||||||
for vol in data['images'].split(','):
|
for idx, vol in enumerate(data['images'].split(',')):
|
||||||
try:
|
try:
|
||||||
|
|
||||||
path = conn.get_volume_path(vol)
|
path = conn.get_volume_path(vol)
|
||||||
volumes[path] = conn.get_volume_type(path)
|
volume = dict()
|
||||||
|
volume['path'] = path
|
||||||
|
volume['type'] = conn.get_volume_type(path)
|
||||||
|
volume['device'] = request.POST.get('device' + str(idx), '')
|
||||||
|
volume['bus'] = request.POST.get('bus' + str(idx), '')
|
||||||
|
volume_list.append(volume)
|
||||||
|
|
||||||
|
#volumes[path] = conn.get_volume_type(path)
|
||||||
|
|
||||||
except libvirtError as lib_err:
|
except libvirtError as lib_err:
|
||||||
error_messages.append(lib_err.message)
|
error_messages.append(lib_err.message)
|
||||||
if data['cache_mode'] not in conn.get_cache_modes():
|
if data['cache_mode'] not in conn.get_cache_modes():
|
||||||
|
@ -143,7 +171,7 @@ def create_instance(request, compute_id):
|
||||||
uuid = util.randomUUID()
|
uuid = util.randomUUID()
|
||||||
try:
|
try:
|
||||||
conn.create_instance(data['name'], data['memory'], data['vcpu'], data['host_model'],
|
conn.create_instance(data['name'], data['memory'], data['vcpu'], data['host_model'],
|
||||||
uuid, volumes, data['cache_mode'], data['networks'], data['virtio'],
|
uuid, volume_list, data['cache_mode'], data['networks'], data['virtio'],
|
||||||
data["listener_addr"], data["nwfilter"], data["video"], data["console_pass"],
|
data["listener_addr"], data["nwfilter"], data["video"], data["console_pass"],
|
||||||
data['mac'])
|
data['mac'])
|
||||||
create_instance = Instance(compute_id=compute_id, name=data['name'], uuid=uuid)
|
create_instance = Instance(compute_id=compute_id, name=data['name'], uuid=uuid)
|
||||||
|
@ -153,8 +181,9 @@ def create_instance(request, compute_id):
|
||||||
addlogmsg(request.user.username, create_instance.name, msg)
|
addlogmsg(request.user.username, create_instance.name, msg)
|
||||||
return HttpResponseRedirect(reverse('instance', args=[compute_id, data['name']]))
|
return HttpResponseRedirect(reverse('instance', args=[compute_id, data['name']]))
|
||||||
except libvirtError as lib_err:
|
except libvirtError as lib_err:
|
||||||
if data['hdd_size'] or volumes[clone_path]:
|
if data['hdd_size'] or volume_list.count() > 0:
|
||||||
conn.delete_volume(volumes.keys()[0])
|
for vol in volume_list:
|
||||||
|
conn.delete_volume(vol['path'])
|
||||||
error_messages.append(lib_err)
|
error_messages.append(lib_err)
|
||||||
conn.close()
|
conn.close()
|
||||||
return render(request, 'create_instance.html', locals())
|
return render(request, 'create_instance.html', locals())
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
{% ifequal status 5 %}
|
{% ifequal status 5 %}
|
||||||
<button type="submit" class="btn btn-lg btn-success pull-right" name="addnewvol">{% trans "Add Volume" %}</button>
|
<button type="submit" class="btn btn-lg btn-success pull-right" name="add_new_vol">{% trans "Add Volume" %}</button>
|
||||||
{% else %}
|
{% else %}
|
||||||
<button class="btn btn-lg btn-success pull-right disabled">{% trans "Add Volume" %}</button>
|
<button class="btn btn-lg btn-success pull-right disabled">{% trans "Add Volume" %}</button>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
|
@ -143,7 +143,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
{% ifequal status 5 %}
|
{% ifequal status 5 %}
|
||||||
<button type="submit" class="btn btn-lg btn-success pull-right" name="addexistingvol">{% trans "Add Volume" %}</button>
|
<button type="submit" class="btn btn-lg btn-success pull-right" name="add_existing_vol">{% trans "Add Volume" %}</button>
|
||||||
{% else %}
|
{% else %}
|
||||||
<button class="btn btn-lg btn-success pull-right disabled">{% trans "Add Volume" %}</button>
|
<button class="btn btn-lg btn-success pull-right disabled">{% trans "Add Volume" %}</button>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
|
|
|
@ -594,10 +594,30 @@
|
||||||
<!-- Tab panes -->
|
<!-- Tab panes -->
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="media">
|
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="media">
|
||||||
|
{% if request.user.is_superuser and status == 5 %}
|
||||||
|
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<button type="submit" name="add_cdrom" type="button" class="btn btn-success pull-right">
|
||||||
|
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
{% for cd in media %}
|
{% for cd in media %}
|
||||||
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
|
<form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-sm-2 control-label">{% trans "CDROM" %} {{ forloop.counter }}</label>
|
<a class="col-sm-2 control-label"
|
||||||
|
name="details"
|
||||||
|
title="{% trans "Details" %}"
|
||||||
|
tabindex="0"
|
||||||
|
data-trigger="focus"
|
||||||
|
data-toggle="popover"
|
||||||
|
data-html="true"
|
||||||
|
data-content="<strong>Bus:</strong> {{ cd.bus }} <br/> <strong>Dev:</strong> {{ cd.dev }}">
|
||||||
|
{% trans "CDROM" %} {{ forloop.counter }}
|
||||||
|
</a>
|
||||||
{% if not cd.image %}
|
{% if not cd.image %}
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<select name="media" class="form-control">
|
<select name="media" class="form-control">
|
||||||
|
@ -613,13 +633,16 @@
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2">
|
||||||
{% if media_iso and allow_admin_or_not_template %}
|
{% if media_iso and allow_admin_or_not_template %}
|
||||||
<button type="submit" class="btn btn-sm btn-success pull-left" name="mount_iso" value="{{ cd.dev }}" style="margin-top: 2px;">{% trans "Mount" %}</button>
|
<button type="submit" class="btn btn-sm btn-success pull-left" name="mount_iso" value="{{ cd.dev }}" style="margin-top: 2px;">{% trans "Mount" %}</button>
|
||||||
|
{% if status == 5 %}
|
||||||
|
<button type="submit" class="btn btn-sm btn-danger pull-left" name="detach_cdrom" value="{{ cd.dev }}" style="margin-top: 2px;"><i class="glyphicon glyphicon-remove-circle"></i></button>
|
||||||
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<button class="btn btn-sm btn-success pull-left disabled" style="margin-top: 2px;">{% trans "Mount" %}</button>
|
<button class="btn btn-sm btn-success pull-left disabled" style="margin-top: 2px;">{% trans "Mount" %}</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="col-sm-5">
|
<div class="col-sm-6">
|
||||||
<p>{{ cd.image }}</p>
|
<input class="form-control" value="{{ cd.image }}" disabled/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2">
|
||||||
<input type="hidden" name="path" value="{{ cd.path }}">
|
<input type="hidden" name="path" value="{{ cd.path }}">
|
||||||
|
@ -677,18 +700,20 @@
|
||||||
<form action="" method="post" style="height:10px" role="form">{% csrf_token %}
|
<form action="" method="post" style="height:10px" role="form">{% csrf_token %}
|
||||||
<input type="hidden" name="path" value="{{ disk.path }}">
|
<input type="hidden" name="path" value="{{ disk.path }}">
|
||||||
<input type="hidden" name="dev" value="{{ disk.dev }}">
|
<input type="hidden" name="dev" value="{{ disk.dev }}">
|
||||||
|
<input type="hidden" name="storage" value="{{ disk.storage }}">
|
||||||
|
<input type="hidden" name="name" value="{{ disk.image }}">
|
||||||
{% ifequal status 5 %}
|
{% ifequal status 5 %}
|
||||||
<button type="submit" class="btn btn-sm btn-default" name="detachvolume" title="{% trans "Detach" %}" onclick="return confirm('{% trans "Are you sure to detach volume?" %}')">
|
<button type="submit" class="btn btn-sm btn-default" name="detach_vol" value="{{ disk.dev }}" title="{% trans "Detach" %}" onclick="return confirm('{% trans "Are you sure to detach volume?" %}')">
|
||||||
<i class="fa fa-eject"></i>
|
<i class="fa fa-eject"></i>
|
||||||
</button>
|
</button>
|
||||||
<button type="submit" class="btn btn-sm btn-default" name="delvolume" title="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure to delete volume?" %}')">
|
<button type="submit" class="btn btn-sm btn-default" name="delete_vol" title="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure to delete volume?" %}')">
|
||||||
<i class="fa fa-trash"></i>
|
<i class="fa fa-trash"></i>
|
||||||
</button>
|
</button>
|
||||||
{% else %}
|
{% else %}
|
||||||
<button class="btn btn-sm btn-default disabled" name="detachvolume" title="{% trans "Detach" %}" onclick="return confirm('{% trans "Are you sure to detach volume after shutdown?" %}')">
|
<button class="btn btn-sm btn-default disabled" name="detach_vol" value="{{ disk.dev }}" title="{% trans "Detach" %}" onclick="return confirm('{% trans "Are you sure to detach volume after shutdown?" %}')">
|
||||||
<i class="fa fa-eject"></i>
|
<i class="fa fa-eject"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-sm btn-default disabled" name="delvolume" title="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure to delete after shutdown?" %}')">
|
<button class="btn btn-sm btn-default disabled" name="delete_vol" title="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure to delete after shutdown?" %}')">
|
||||||
<i class="fa fa-trash"></i>
|
<i class="fa fa-trash"></i>
|
||||||
</button>
|
</button>
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
|
@ -1243,13 +1268,20 @@
|
||||||
{% block script %}
|
{% block script %}
|
||||||
<script src="{% static "js/ace.js" %}" type="text/javascript" charset="utf-8"></script>
|
<script src="{% static "js/ace.js" %}" type="text/javascript" charset="utf-8"></script>
|
||||||
<script>
|
<script>
|
||||||
function get_volumes(comp_id, pool) {
|
function get_volumes(compute_id, pool) {
|
||||||
vol_url = "/computes/" + comp_id + "/storage/" + pool + "/?get_volumes";
|
|
||||||
var select = document.getElementById("vols");
|
|
||||||
|
|
||||||
while (select.options.length){
|
|
||||||
select.removeChild(select.options[0]);
|
get_vol_url = "/computes/" + compute_id + "/storage/" + pool + "/volumes";
|
||||||
}
|
$.getJSON(get_vol_url, function (data) {
|
||||||
|
$("#vols").find('option').remove();
|
||||||
|
$("#vols").removeAttr("disabled");
|
||||||
|
|
||||||
|
$.each(data['vols'], function(i, item) {
|
||||||
|
$("#vols").append('<option value=' + item +'>' + item + '</option>');
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
var sto_drop = document.getElementById('select_storage');
|
var sto_drop = document.getElementById('select_storage');
|
||||||
sto_drop.value = pool;
|
sto_drop.value = pool;
|
||||||
|
@ -1259,22 +1291,6 @@
|
||||||
sto_input.value = pool;
|
sto_input.value = pool;
|
||||||
sto_input.innerHTML = pool;
|
sto_input.innerHTML = pool;
|
||||||
|
|
||||||
$.getJSON(vol_url, function(data) {
|
|
||||||
if (data.length > 0) {
|
|
||||||
select.disabled = false;
|
|
||||||
}
|
|
||||||
var opt = document.createElement('option');
|
|
||||||
opt.value = '';
|
|
||||||
opt.innerHTML = 'None';
|
|
||||||
select.appendChild(opt);
|
|
||||||
for (i = 0; i < data.length; i++){
|
|
||||||
var opt = document.createElement('option');
|
|
||||||
opt.value = data[i]['name'];
|
|
||||||
opt.innerHTML = data[i]['name'];
|
|
||||||
select.appendChild(opt);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -197,12 +197,18 @@ def instance(request, compute_id, vname):
|
||||||
def get_new_disk_dev(disks, bus):
|
def get_new_disk_dev(disks, bus):
|
||||||
if bus == "virtio":
|
if bus == "virtio":
|
||||||
dev_base = "vd"
|
dev_base = "vd"
|
||||||
|
elif bus == "ide":
|
||||||
|
dev_base = "hd"
|
||||||
|
elif bus == "fdc":
|
||||||
|
dev_base = "fd"
|
||||||
else:
|
else:
|
||||||
dev_base = "sd"
|
dev_base = "sd"
|
||||||
existing_devs = [disk['dev'] for disk in disks]
|
existing_disk_devs = [disk['dev'] for disk in disks]
|
||||||
|
# cd-rom bus could be virtio/sata, because of that we should check it also
|
||||||
|
existing_media_devs = [disk['dev'] for disk in media]
|
||||||
for l in string.lowercase:
|
for l in string.lowercase:
|
||||||
dev = dev_base + l
|
dev = dev_base + l
|
||||||
if dev not in existing_devs:
|
if dev not in existing_disk_devs and dev not in existing_media_devs:
|
||||||
return dev
|
return dev
|
||||||
raise Exception(_('None available device name'))
|
raise Exception(_('None available device name'))
|
||||||
|
|
||||||
|
@ -290,7 +296,7 @@ def instance(request, compute_id, vname):
|
||||||
default_owner = settings.INSTANCE_VOLUME_DEFAULT_OWNER
|
default_owner = settings.INSTANCE_VOLUME_DEFAULT_OWNER
|
||||||
formats = conn.get_image_formats()
|
formats = conn.get_image_formats()
|
||||||
|
|
||||||
busses = conn.get_busses()
|
busses = conn.get_disk_bus_types()
|
||||||
default_bus = settings.INSTANCE_VOLUME_DEFAULT_BUS
|
default_bus = settings.INSTANCE_VOLUME_DEFAULT_BUS
|
||||||
show_access_root_password = settings.SHOW_ACCESS_ROOT_PASSWORD
|
show_access_root_password = settings.SHOW_ACCESS_ROOT_PASSWORD
|
||||||
show_access_ssh_keys = settings.SHOW_ACCESS_SSH_KEYS
|
show_access_ssh_keys = settings.SHOW_ACCESS_SSH_KEYS
|
||||||
|
@ -445,7 +451,7 @@ def instance(request, compute_id, vname):
|
||||||
addlogmsg(request.user.username, instance.name, msg)
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
return HttpResponseRedirect(request.get_full_path() + '#resize')
|
return HttpResponseRedirect(request.get_full_path() + '#resize')
|
||||||
|
|
||||||
if 'addnewvol' in request.POST and allow_admin_or_not_template:
|
if 'add_new_vol' in request.POST and allow_admin_or_not_template:
|
||||||
connCreate = wvmCreate(compute.hostname,
|
connCreate = wvmCreate(compute.hostname,
|
||||||
compute.login,
|
compute.login,
|
||||||
compute.password,
|
compute.password,
|
||||||
|
@ -461,11 +467,11 @@ def instance(request, compute_id, vname):
|
||||||
|
|
||||||
path = connCreate.create_volume(storage, name, size, format, meta_prealloc, default_owner)
|
path = connCreate.create_volume(storage, name, size, format, meta_prealloc, default_owner)
|
||||||
conn.attach_disk(path, target, subdriver=format, cache=cache, targetbus=bus)
|
conn.attach_disk(path, target, subdriver=format, cache=cache, targetbus=bus)
|
||||||
msg = _('Attach new disk')
|
msg = _('Attach new disk: ' + target)
|
||||||
addlogmsg(request.user.username, instance.name, msg)
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
||||||
|
|
||||||
if 'addexistingvol' in request.POST and allow_admin_or_not_template:
|
if 'add_existing_vol' in request.POST and allow_admin_or_not_template:
|
||||||
storage = request.POST.get('selected_storage', '')
|
storage = request.POST.get('selected_storage', '')
|
||||||
name = request.POST.get('vols', '')
|
name = request.POST.get('vols', '')
|
||||||
bus = request.POST.get('bus', default_bus)
|
bus = request.POST.get('bus', default_bus)
|
||||||
|
@ -483,42 +489,57 @@ def instance(request, compute_id, vname):
|
||||||
source = path + "/" + name;
|
source = path + "/" + name;
|
||||||
|
|
||||||
conn.attach_disk(source, target, subdriver=format, cache=cache, targetbus=bus)
|
conn.attach_disk(source, target, subdriver=format, cache=cache, targetbus=bus)
|
||||||
msg = _('Attach Existing disk')
|
msg = _('Attach Existing disk: ' + target)
|
||||||
addlogmsg(request.user.username, instance.name, msg)
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
||||||
|
|
||||||
if 'delvolume' in request.POST and allow_admin_or_not_template:
|
if 'delete_vol' in request.POST and allow_admin_or_not_template:
|
||||||
connDelete = wvmCreate(compute.hostname,
|
storage = request.POST.get('storage', '')
|
||||||
compute.login,
|
connDelete = wvmStorage(compute.hostname,
|
||||||
compute.password,
|
compute.login,
|
||||||
compute.type)
|
compute.password,
|
||||||
|
compute.type,
|
||||||
|
storage)
|
||||||
dev = request.POST.get('dev', '')
|
dev = request.POST.get('dev', '')
|
||||||
path = request.POST.get('path', '')
|
path = request.POST.get('path', '')
|
||||||
|
name = request.POST.get('name', '')
|
||||||
|
|
||||||
conn.detach_disk(dev, path)
|
conn.detach_disk(dev)
|
||||||
connDelete.delete_volume(path)
|
connDelete.del_volume(name)
|
||||||
|
|
||||||
msg = _('Delete disk')
|
msg = _('Delete disk: ' + dev)
|
||||||
addlogmsg(request.user.username, instance.name, msg)
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
||||||
|
|
||||||
if 'detachvolume' in request.POST and allow_admin_or_not_template:
|
if 'detach_vol' in request.POST and allow_admin_or_not_template:
|
||||||
connDelete = wvmCreate(compute.hostname,
|
dev = request.POST.get('detach_vol', '')
|
||||||
compute.login,
|
|
||||||
compute.password,
|
|
||||||
compute.type)
|
|
||||||
dev = request.POST.get('dev', '')
|
|
||||||
path = request.POST.get('path', '')
|
path = request.POST.get('path', '')
|
||||||
conn.detach_disk(dev, path)
|
conn.detach_disk(dev)
|
||||||
msg = _('Detach disk')
|
msg = _('Detach disk: ' + dev)
|
||||||
addlogmsg(request.user.username, instance.name, msg)
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
return HttpResponseRedirect(request.get_full_path() + '#disks')
|
||||||
|
|
||||||
|
if 'add_cdrom' in request.POST and allow_admin_or_not_template:
|
||||||
|
bus = request.POST.get('bus', 'ide')
|
||||||
|
target = get_new_disk_dev(media, bus)
|
||||||
|
conn.attach_disk("", target, device='cdrom', cache='none', targetbus=bus)
|
||||||
|
msg = _('Add CD-Rom: ' + target)
|
||||||
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
|
return HttpResponseRedirect(request.get_full_path() + '#media')
|
||||||
|
|
||||||
|
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)
|
||||||
|
msg = _('Detach CD-Rom: ' + dev)
|
||||||
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
|
return HttpResponseRedirect(request.get_full_path() + '#media')
|
||||||
|
|
||||||
if 'umount_iso' in request.POST and allow_admin_or_not_template:
|
if 'umount_iso' in request.POST and allow_admin_or_not_template:
|
||||||
image = request.POST.get('path', '')
|
image = request.POST.get('path', '')
|
||||||
dev = request.POST.get('umount_iso', '')
|
dev = request.POST.get('umount_iso', '')
|
||||||
conn.umount_iso(dev, image)
|
conn.umount_iso(dev, image)
|
||||||
msg = _("Mount media")
|
msg = _("Mount media: " + dev)
|
||||||
addlogmsg(request.user.username, instance.name, msg)
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
return HttpResponseRedirect(request.get_full_path() + '#media')
|
return HttpResponseRedirect(request.get_full_path() + '#media')
|
||||||
|
|
||||||
|
@ -526,21 +547,21 @@ def instance(request, compute_id, vname):
|
||||||
image = request.POST.get('media', '')
|
image = request.POST.get('media', '')
|
||||||
dev = request.POST.get('mount_iso', '')
|
dev = request.POST.get('mount_iso', '')
|
||||||
conn.mount_iso(dev, image)
|
conn.mount_iso(dev, image)
|
||||||
msg = _("Umount media")
|
msg = _("Umount media: " + dev)
|
||||||
addlogmsg(request.user.username, instance.name, msg)
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
return HttpResponseRedirect(request.get_full_path() + '#media')
|
return HttpResponseRedirect(request.get_full_path() + '#media')
|
||||||
|
|
||||||
if 'snapshot' in request.POST and allow_admin_or_not_template:
|
if 'snapshot' in request.POST and allow_admin_or_not_template:
|
||||||
name = request.POST.get('name', '')
|
name = request.POST.get('name', '')
|
||||||
conn.create_snapshot(name)
|
conn.create_snapshot(name)
|
||||||
msg = _("New snapshot")
|
msg = _("New snapshot :" + name)
|
||||||
addlogmsg(request.user.username, instance.name, msg)
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
return HttpResponseRedirect(request.get_full_path() + '#managesnapshot')
|
return HttpResponseRedirect(request.get_full_path() + '#managesnapshot')
|
||||||
|
|
||||||
if 'delete_snapshot' in request.POST and allow_admin_or_not_template:
|
if 'delete_snapshot' in request.POST and allow_admin_or_not_template:
|
||||||
snap_name = request.POST.get('name', '')
|
snap_name = request.POST.get('name', '')
|
||||||
conn.snapshot_delete(snap_name)
|
conn.snapshot_delete(snap_name)
|
||||||
msg = _("Delete snapshot")
|
msg = _("Delete snapshot :" + snap_name)
|
||||||
addlogmsg(request.user.username, instance.name, msg)
|
addlogmsg(request.user.username, instance.name, msg)
|
||||||
return HttpResponseRedirect(request.get_full_path() + '#managesnapshot')
|
return HttpResponseRedirect(request.get_full_path() + '#managesnapshot')
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ class wvmCreate(wvmConnect):
|
||||||
def get_volume_type(self, path):
|
def get_volume_type(self, path):
|
||||||
vol = self.get_volume_by_path(path)
|
vol = self.get_volume_by_path(path)
|
||||||
vol_type = util.get_xml_path(vol.XMLDesc(0), "/volume/target/format/@type")
|
vol_type = util.get_xml_path(vol.XMLDesc(0), "/volume/target/format/@type")
|
||||||
if vol_type == 'unknown':
|
if vol_type == 'unknown' or vol_type == 'iso':
|
||||||
return 'raw'
|
return 'raw'
|
||||||
if vol_type:
|
if vol_type:
|
||||||
return vol_type
|
return vol_type
|
||||||
|
@ -189,11 +189,18 @@ class wvmCreate(wvmConnect):
|
||||||
<on_crash>restart</on_crash>
|
<on_crash>restart</on_crash>
|
||||||
<devices>"""
|
<devices>"""
|
||||||
|
|
||||||
disk_letters = list(string.lowercase)
|
vd_disk_letters = list(string.lowercase)
|
||||||
for image, img_type in images.items():
|
fd_disk_letters = list(string.lowercase)
|
||||||
stg = self.get_storage_by_vol_path(image)
|
hd_disk_letters = list(string.lowercase)
|
||||||
|
sd_disk_letters = list(string.lowercase)
|
||||||
|
add_cd = True
|
||||||
|
#for image, img_type in images.items():
|
||||||
|
for volume in images:
|
||||||
|
stg = self.get_storage_by_vol_path(volume['path'])
|
||||||
stg_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type")
|
stg_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type")
|
||||||
|
|
||||||
|
if volume['device'] == 'cdrom': add_cd = False
|
||||||
|
|
||||||
if stg_type == 'rbd':
|
if stg_type == 'rbd':
|
||||||
ceph_user, secret_uuid, ceph_hosts = get_rbd_storage_data(stg)
|
ceph_user, secret_uuid, ceph_hosts = get_rbd_storage_data(stg)
|
||||||
xml += """<disk type='network' device='disk'>
|
xml += """<disk type='network' device='disk'>
|
||||||
|
@ -201,7 +208,7 @@ class wvmCreate(wvmConnect):
|
||||||
<auth username='%s'>
|
<auth username='%s'>
|
||||||
<secret type='ceph' uuid='%s'/>
|
<secret type='ceph' uuid='%s'/>
|
||||||
</auth>
|
</auth>
|
||||||
<source protocol='rbd' name='%s'>""" % (img_type, cache_mode, ceph_user, secret_uuid, image)
|
<source protocol='rbd' name='%s'>""" % (volume['type'], cache_mode, ceph_user, secret_uuid, volume['path'])
|
||||||
if isinstance(ceph_hosts, list):
|
if isinstance(ceph_hosts, list):
|
||||||
for host in ceph_hosts:
|
for host in ceph_hosts:
|
||||||
if host.get('port'):
|
if host.get('port'):
|
||||||
|
@ -213,23 +220,26 @@ class wvmCreate(wvmConnect):
|
||||||
xml += """
|
xml += """
|
||||||
</source>"""
|
</source>"""
|
||||||
else:
|
else:
|
||||||
xml += """<disk type='file' device='disk'>
|
xml += """<disk type='file' device='%s'>
|
||||||
<driver name='qemu' type='%s' cache='%s'/>
|
<driver name='qemu' type='%s' cache='%s'/>
|
||||||
<source file='%s'/>""" % (img_type, cache_mode, image)
|
<source file='%s'/>""" % (volume['device'], volume['type'], cache_mode, volume['path'])
|
||||||
|
|
||||||
if virtio:
|
if volume['bus'] == 'virtio':
|
||||||
xml += """<target dev='vd%s' bus='virtio'/>""" % (disk_letters.pop(0),)
|
xml += """<target dev='vd%s' bus='%s'/>""" % (vd_disk_letters.pop(0), volume['bus'])
|
||||||
|
elif volume['bus'] == 'ide':
|
||||||
|
xml += """<target dev='hd%s' bus='%s'/>""" % (hd_disk_letters.pop(0), volume['bus'])
|
||||||
|
elif volume['bus'] == 'fdc':
|
||||||
|
xml += """<target dev='fd%s' bus='%s'/>""" % (fd_disk_letters.pop(0), volume['bus'])
|
||||||
else:
|
else:
|
||||||
xml += """<target dev='sd%s' bus='ide'/>""" % (disk_letters.pop(0),)
|
xml += """<target dev='sd%s' bus='%s'/>""" % (sd_disk_letters.pop(0), volume['bus'])
|
||||||
xml += """</disk>"""
|
xml += """</disk>"""
|
||||||
|
if add_cd:
|
||||||
xml += """ <disk type='file' device='cdrom'>
|
xml += """ <disk type='file' device='cdrom'>
|
||||||
<driver name='qemu' type='raw'/>
|
<driver name='qemu' type='raw'/>
|
||||||
<source file=''/>
|
<source file=''/>
|
||||||
<target dev='hda' bus='ide'/>
|
<target dev='hd%s' bus='ide'/>
|
||||||
<readonly/>
|
<readonly/>
|
||||||
<address type='drive' controller='0' bus='1' target='0' unit='1'/>
|
</disk>""" % (hd_disk_letters.pop(0),)
|
||||||
</disk>"""
|
|
||||||
for net in networks.split(','):
|
for net in networks.split(','):
|
||||||
xml += """<interface type='network'>"""
|
xml += """<interface type='network'>"""
|
||||||
if mac:
|
if mac:
|
||||||
|
|
Loading…
Reference in a new issue