mirror of
https://github.com/retspen/webvirtcloud
synced 2024-12-25 15:45:23 +00:00
Instance create with template is revisited. Add password, console, listener address options. add wait dialog. change to console password optional. nwfilter become option.
This commit is contained in:
parent
f477dd6a11
commit
b58277c621
4 changed files with 61 additions and 14 deletions
|
@ -2,6 +2,7 @@ import re
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from create.models import Flavor
|
from create.models import Flavor
|
||||||
|
from webvirtcloud.settings import QEMU_CONSOLE_LISTEN_ADDRESSES
|
||||||
|
|
||||||
|
|
||||||
class FlavorAddForm(forms.Form):
|
class FlavorAddForm(forms.Form):
|
||||||
|
@ -45,6 +46,9 @@ class NewVMForm(forms.Form):
|
||||||
meta_prealloc = forms.BooleanField(required=False)
|
meta_prealloc = forms.BooleanField(required=False)
|
||||||
virtio = forms.BooleanField(required=False)
|
virtio = forms.BooleanField(required=False)
|
||||||
mac = forms.CharField(required=False)
|
mac = forms.CharField(required=False)
|
||||||
|
console_pass = forms.CharField(required=False,empty_value="", widget=forms.PasswordInput())
|
||||||
|
video = forms.CharField(error_messages={'required': _('Please select a graphic display')})
|
||||||
|
listener_addr = forms.ChoiceField(required=True, widget=forms.RadioSelect, choices=QEMU_CONSOLE_LISTEN_ADDRESSES)
|
||||||
|
|
||||||
def clean_name(self):
|
def clean_name(self):
|
||||||
name = self.cleaned_data['name']
|
name = self.cleaned_data['name']
|
||||||
|
@ -54,3 +58,4 @@ class NewVMForm(forms.Form):
|
||||||
elif len(name) > 20:
|
elif len(name) > 20:
|
||||||
raise forms.ValidationError(_('The name of the virtual machine must not exceed 20 characters'))
|
raise forms.ValidationError(_('The name of the virtual machine must not exceed 20 characters'))
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- /.row -->
|
<!-- /.row -->
|
||||||
|
|
||||||
{% include 'errors_block.html' %}
|
{% include 'errors_block.html' %}
|
||||||
|
{% include 'pleasewaitdialog.html' %}
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
|
@ -115,7 +115,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if storages %}
|
{% if storages %}
|
||||||
<button type="submit" class="btn btn-primary" name="create" value="1">
|
<button type="submit" class="btn btn-primary" name="create" onclick="showPleaseWaitDialog()" value="1">
|
||||||
{% trans "Create" %}
|
{% trans "Create" %}
|
||||||
</button>
|
</button>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -202,8 +202,35 @@
|
||||||
<input type="checkbox" name="virtio" value="true" checked>
|
<input type="checkbox" name="virtio" value="true" checked>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "Video" %}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<select name="video" class="form-control">
|
||||||
|
{% for video in videos %}
|
||||||
|
<option value="{{ video }}">{{ video }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "Console Password" %}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<input type="password" class="form-control" name="console_pass" placeholder="{% trans "Console Password" %}" maxlength="14">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">{% trans "Console Access" %}</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<select name="listener_addr" class="form-control">
|
||||||
|
{% for addr, label in listener_addr %}
|
||||||
|
<option value="{{ addr }}" {% if addr == "0.0.0.0" %} selected {% endif %}>{{ label }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% if storages %}
|
{% if storages %}
|
||||||
<button type="submit" class="btn btn-primary" name="create" value="1">
|
<button type="submit" class="btn btn-primary" name="create" value="1" onclick="showPleaseWaitDialog()">
|
||||||
{% trans "Create" %}
|
{% trans "Create" %}
|
||||||
</button>
|
</button>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
|
@ -10,7 +10,8 @@ from instances.models import Instance
|
||||||
from vrtManager.create import wvmCreate
|
from vrtManager.create import wvmCreate
|
||||||
from vrtManager import util
|
from vrtManager import util
|
||||||
from libvirt import libvirtError
|
from libvirt import libvirtError
|
||||||
|
from webvirtcloud.settings import QEMU_CONSOLE_LISTEN_ADDRESSES
|
||||||
|
from django.contrib import messages
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def create_instance(request, compute_id):
|
def create_instance(request, compute_id):
|
||||||
|
@ -27,7 +28,7 @@ def create_instance(request, compute_id):
|
||||||
storages = []
|
storages = []
|
||||||
networks = []
|
networks = []
|
||||||
meta_prealloc = False
|
meta_prealloc = False
|
||||||
computes = Compute.objects.all()
|
#computes = Compute.objects.all()
|
||||||
compute = get_object_or_404(Compute, pk=compute_id)
|
compute = get_object_or_404(Compute, pk=compute_id)
|
||||||
flavors = Flavor.objects.filter().order_by('id')
|
flavors = Flavor.objects.filter().order_by('id')
|
||||||
|
|
||||||
|
@ -40,7 +41,9 @@ def create_instance(request, compute_id):
|
||||||
storages = sorted(conn.get_storages(only_actives=True))
|
storages = sorted(conn.get_storages(only_actives=True))
|
||||||
networks = sorted(conn.get_networks())
|
networks = sorted(conn.get_networks())
|
||||||
instances = conn.get_instances()
|
instances = conn.get_instances()
|
||||||
|
videos = conn.get_video()
|
||||||
cache_modes = sorted(conn.get_cache_modes().items())
|
cache_modes = sorted(conn.get_cache_modes().items())
|
||||||
|
listener_addr = QEMU_CONSOLE_LISTEN_ADDRESSES
|
||||||
mac_auto = util.randomMAC()
|
mac_auto = util.randomMAC()
|
||||||
get_images = sorted(conn.get_storages_images())
|
get_images = sorted(conn.get_storages_images())
|
||||||
except libvirtError as lib_err:
|
except libvirtError as lib_err:
|
||||||
|
@ -110,6 +113,11 @@ def create_instance(request, compute_id):
|
||||||
error_messages.append(lib_err.message)
|
error_messages.append(lib_err.message)
|
||||||
elif data['template']:
|
elif data['template']:
|
||||||
templ_path = conn.get_volume_path(data['template'])
|
templ_path = conn.get_volume_path(data['template'])
|
||||||
|
dest_vol = conn.get_volume_path(data["name"] + ".img")
|
||||||
|
if dest_vol:
|
||||||
|
error_msg = _("Image has already exist. Please check volumes or change instance name")
|
||||||
|
error_messages.append(error_msg)
|
||||||
|
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)
|
volumes[clone_path] = conn.get_volume_type(clone_path)
|
||||||
else:
|
else:
|
||||||
|
@ -131,12 +139,14 @@ def create_instance(request, compute_id):
|
||||||
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, volumes, data['cache_mode'], data['networks'], data['virtio'],
|
||||||
|
data["console_pass"], data["listener_addr"], None, data["video"],
|
||||||
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)
|
||||||
create_instance.save()
|
create_instance.save()
|
||||||
|
messages.success(request,"Instance is created.")
|
||||||
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']:
|
if data['hdd_size'] or volumes[clone_path]:
|
||||||
conn.delete_volume(volumes.keys()[0])
|
conn.delete_volume(volumes.keys()[0])
|
||||||
error_messages.append(lib_err)
|
error_messages.append(lib_err)
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
|
@ -2,6 +2,7 @@ import string
|
||||||
from vrtManager import util
|
from vrtManager import util
|
||||||
from vrtManager.connection import wvmConnect
|
from vrtManager.connection import wvmConnect
|
||||||
from webvirtcloud.settings import QEMU_CONSOLE_DEFAULT_TYPE
|
from webvirtcloud.settings import QEMU_CONSOLE_DEFAULT_TYPE
|
||||||
|
from webvirtcloud.settings import QEMU_CONSOLE_LISTEN_ADDRESSES
|
||||||
from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_FORMAT
|
from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_FORMAT
|
||||||
|
|
||||||
|
|
||||||
|
@ -148,7 +149,7 @@ class wvmCreate(wvmConnect):
|
||||||
vol = self.get_volume_by_path(path)
|
vol = self.get_volume_by_path(path)
|
||||||
vol.delete()
|
vol.delete()
|
||||||
|
|
||||||
def create_instance(self, name, memory, vcpu, host_model, uuid, images, cache_mode, networks, virtio, mac=None):
|
def create_instance(self, name, memory, vcpu, host_model, uuid, images, cache_mode, networks, virtio, console_pass, listen_addr, nwfilter=None, video="cirrus", mac=None ):
|
||||||
"""
|
"""
|
||||||
Create VM function
|
Create VM function
|
||||||
"""
|
"""
|
||||||
|
@ -228,20 +229,24 @@ class wvmCreate(wvmConnect):
|
||||||
xml += """<interface type='network'>"""
|
xml += """<interface type='network'>"""
|
||||||
if mac:
|
if mac:
|
||||||
xml += """<mac address='%s'/>""" % mac
|
xml += """<mac address='%s'/>""" % mac
|
||||||
xml += """<source network='%s'/>
|
xml += """<source network='%s'/>""" % net
|
||||||
<filterref filter='clean-traffic'/>""" % net
|
if nwfilter:
|
||||||
|
xml += """<filterref filter='%s'/>""" % nwfilter
|
||||||
if virtio:
|
if virtio:
|
||||||
xml += """<model type='virtio'/>"""
|
xml += """<model type='virtio'/>"""
|
||||||
xml += """</interface>"""
|
xml += """</interface>"""
|
||||||
|
|
||||||
|
if console_pass is None: console_pass = "passwd='" + util.randomPasswd() + "'"
|
||||||
|
else: console_pass = "passwd='" + console_pass + "'"
|
||||||
|
|
||||||
xml += """ <input type='mouse' bus='ps2'/>
|
xml += """ <input type='mouse' bus='ps2'/>
|
||||||
<input type='tablet' bus='usb'/>
|
<input type='tablet' bus='usb'/>
|
||||||
<graphics type='%s' port='-1' autoport='yes' passwd='%s' listen='127.0.0.1'/>
|
<graphics type='%s' port='-1' autoport='yes' %s listen='%s'/>
|
||||||
<console type='pty'/>
|
<console type='pty'/>
|
||||||
<video>
|
<video>
|
||||||
<model type='cirrus'/>
|
<model type='%s'/>
|
||||||
</video>
|
</video>
|
||||||
<memballoon model='virtio'/>
|
<memballoon model='virtio'/>
|
||||||
</devices>
|
</devices>
|
||||||
</domain>""" % (QEMU_CONSOLE_DEFAULT_TYPE, util.randomPasswd())
|
</domain>""" % (QEMU_CONSOLE_DEFAULT_TYPE, console_pass, listen_addr, video)
|
||||||
self._defineXML(xml)
|
self._defineXML(xml)
|
||||||
|
|
Loading…
Reference in a new issue