1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2024-12-24 15:15:22 +00:00

Merge pull request #175 from honza801/master

some fixes
This commit is contained in:
Anatoliy Guskov 2018-08-24 18:08:19 +03:00 committed by GitHub
commit 3f98aa2370
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 80 additions and 7 deletions

View file

@ -32,7 +32,7 @@ print(''.join([random.SystemRandom().choice(haystack) for _ in range(50)]))
### Install WebVirtCloud panel (Ubuntu) ### Install WebVirtCloud panel (Ubuntu)
```bash ```bash
sudo apt-get -y install git python-virtualenv python-dev python-lxml libvirt-dev zlib1g-dev nginx supervisor libsasl2-modules gcc pkg-config python-guestfs sudo apt-get -y install git python-virtualenv python-dev python-lxml libvirt-dev zlib1g-dev libxslt1-dev nginx supervisor libsasl2-modules gcc pkg-config python-guestfs
git clone https://github.com/retspen/webvirtcloud git clone https://github.com/retspen/webvirtcloud
cd webvirtcloud cd webvirtcloud
cp webvirtcloud/settings.py.template webvirtcloud/settings.py cp webvirtcloud/settings.py.template webvirtcloud/settings.py

View file

@ -56,6 +56,9 @@ def profile(request):
if keypublic == key.keypublic: if keypublic == key.keypublic:
msg = _("Public key already exist") msg = _("Public key already exist")
error_messages.append(msg) error_messages.append(msg)
if '\n' in keypublic or '\r' in keypublic:
msg = _("Invalid characters in public key")
error_messages.append(msg)
if not error_messages: if not error_messages:
addkeypublic = UserSSHKey(user_id=request.user.id, keyname=keyname, keypublic=keypublic) addkeypublic = UserSSHKey(user_id=request.user.id, keyname=keyname, keypublic=keypublic)
addkeypublic.save() addkeypublic.save()

View file

@ -2,4 +2,6 @@ Django==1.11.14
websockify==0.8.0 websockify==0.8.0
gunicorn==19.9.0 gunicorn==19.9.0
lxml==4.2.3 lxml==4.2.3
libvirt-python==4.4.0 libvirt-python==4.4.0
pytz

View file

@ -8,4 +8,6 @@ urlpatterns = [
views.os_metadata_json, name='ds_openstack_metadata'), views.os_metadata_json, name='ds_openstack_metadata'),
url(r'^openstack/(?P<version>[\w\-\.]+)/user_data$', url(r'^openstack/(?P<version>[\w\-\.]+)/user_data$',
views.os_userdata, name='ds_openstack_userdata'), views.os_userdata, name='ds_openstack_userdata'),
url(r'^vdi/(?P<vname>[\w\-\.]+)/$',
views.get_vdi_url, name='vdi_url'),
] ]

View file

@ -1,6 +1,9 @@
from django.shortcuts import render from django.shortcuts import render
from django.http import HttpResponse, Http404 from django.http import HttpResponse, Http404
from accounts.models import UserInstance, UserSSHKey from accounts.models import UserInstance, UserSSHKey
from instances.models import Instance
from vrtManager.instance import wvmInstance
from libvirt import libvirtError
import json import json
import socket import socket
@ -62,3 +65,24 @@ def get_client_ip(request):
def get_hostname_by_ip(ip): def get_hostname_by_ip(ip):
addrs = socket.gethostbyaddr(ip) addrs = socket.gethostbyaddr(ip)
return addrs[0] return addrs[0]
def get_vdi_url(request, vname):
instance = Instance.objects.get(name=vname)
compute = instance.compute
data = {}
try:
conn = wvmInstance(compute.hostname,
compute.login,
compute.password,
compute.type,
instance.name)
fqdn = get_hostname_by_ip(compute.hostname)
url = "{}://{}:{}".format(conn.get_console_type(), fqdn, conn.get_console_port())
response = url
return HttpResponse(response)
except libvirtError as lib_err:
err = "Error getting vdi url for {}".format(vname)
raise Http404(err)

View file

@ -36,7 +36,7 @@
{% endfor %} {% endfor %}
<a href="{% url 'instance' compute.id vname %}" type="button" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-refresh"></span></a> <a href="{% url 'instance' compute.id vname %}" type="button" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-refresh"></span></a>
<em>on</em> <em>on</em>
<a href="{% url 'overview' compute.id %}"><span class="label label-primary">{{ compute.name}} - {{ compute.hostname }} </span></a> <a href="{% url 'overview' compute.id %}"><span class="label label-primary">{{ compute.name }}{% if compute.name != compute.hostname %} - {{ compute.hostname }}{% endif %} </span></a>
</div> </div>
</div> </div>
{% if user_quota_msg %} {% if user_quota_msg %}
@ -243,6 +243,13 @@
</a> </a>
</li> </li>
{% endif %} {% endif %}
{% ifequal status 1 %}
<li role="presentation">
<a href="#vdiconsole" aria-controls="vdiconsole" role="tab" data-toggle="tab">
{% trans "VDI" %}
</a>
</li>
{% endifequal %}
</ul> </ul>
<!-- Tab panes --> <!-- Tab panes -->
<div class="tab-content"> <div class="tab-content">
@ -311,6 +318,13 @@
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
{% endif %} {% endif %}
{% ifequal status 1 %}
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="vdiconsole">
<p>{% trans "This action opens a remote viewer with a connection to the console of the instance." %}</p>
<a href="#" class="btn btn-lg btn-success pull-right" id="vdi_url" >{% trans "VDI" %}</a>
<div class="clearfix"></div>
</div>
{% endifequal %}
</div> </div>
</div> </div>
</div> </div>
@ -860,6 +874,10 @@
<button type="button" class="btn btn-sm btn-success pull-left" name="guess-clone-name" <button type="button" class="btn btn-sm btn-success pull-left" name="guess-clone-name"
onclick="guess_clone_name()" style="margin-top: 2px;">{% trans "Guess" %}</button> onclick="guess_clone_name()" style="margin-top: 2px;">{% trans "Guess" %}</button>
</div> </div>
{% elif clone_instance_auto_name %}
<div class="col-sm-4">
<input id="clone_instance_auto_name" type="text" class="form-control" name="auto_name" value="Automatic" disabled/>
</div>
{% else %} {% else %}
<div class="col-sm-4"> <div class="col-sm-4">
<select id="select_clone_name" class="form-control" name="name" size="1"/> <select id="select_clone_name" class="form-control" name="name" size="1"/>
@ -1027,7 +1045,7 @@
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">{% trans "Is template" %}</label> <label class="col-sm-3 control-label">{% trans "Is template" %}</label>
<div class="col-sm-6"> <div class="col-sm-6">
<input type="checkbox" name="is_template" value="true" id="is_template" {% if instance.is_template %}checked{% endif %} {% if not request.user.is_superuser %}disabled{% endif %}> <input type="checkbox" name="is_template" value="True" id="is_template" {% if instance.is_template %}checked{% endif %} {% if not request.user.is_superuser %}disabled{% endif %}>
</div> </div>
</div> </div>
{% ifequal status 5 %} {% ifequal status 5 %}
@ -1210,7 +1228,7 @@
} }
</script> </script>
<script> <script>
function random_mac(net) { function random_mac(net) {
$.getJSON('/instance/random_mac_address/', function(data) { $.getJSON('/instance/random_mac_address/', function(data) {
$('input[name="clone-net-mac-'+net+'"]').val(data['mac']); $('input[name="clone-net-mac-'+net+'"]').val(data['mac']);
}); });
@ -1313,6 +1331,12 @@
$("#console_select_listen_address option[value='" + console_listen_address + "']").prop('selected', true); $("#console_select_listen_address option[value='" + console_listen_address + "']").prop('selected', true);
} }
}); });
$(document).ready(function () {
// set vdi url
$.get("/datasource/vdi/{{ vname }}/", function(data) {
$("#vdi_url").attr("href", data);
});
});
{% if request.user.is_superuser %} {% if request.user.is_superuser %}
$(document).ready(function () { $(document).ready(function () {
random_mac(0); random_mac(0);

View file

@ -357,6 +357,7 @@ def instance(request, compute_id, vname):
console_type = conn.get_console_type() console_type = conn.get_console_type()
console_port = conn.get_console_port() console_port = conn.get_console_port()
console_keymap = conn.get_console_keymap() console_keymap = conn.get_console_keymap()
console_listen_address = conn.get_console_listen_addr()
snapshots = sorted(conn.get_snapshot(), reverse=True, key=lambda k:k['date']) snapshots = sorted(conn.get_snapshot(), reverse=True, key=lambda k:k['date'])
inst_xml = conn._XMLDesc(VIR_DOMAIN_XML_SECURE) inst_xml = conn._XMLDesc(VIR_DOMAIN_XML_SECURE)
has_managed_save_image = conn.get_managed_save_image() has_managed_save_image = conn.get_managed_save_image()
@ -375,6 +376,7 @@ def instance(request, compute_id, vname):
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
clone_instance_auto_name = settings.CLONE_INSTANCE_AUTO_NAME
try: try:
instance = Instance.objects.get(compute_id=compute_id, name=vname) instance = Instance.objects.get(compute_id=compute_id, name=vname)
@ -733,6 +735,21 @@ def instance(request, compute_id, vname):
for post in request.POST: for post in request.POST:
clone_data[post] = request.POST.get(post, '').strip() clone_data[post] = request.POST.get(post, '').strip()
if clone_instance_auto_name and not clone_data['name']:
auto_vname = clone_free_names[0]
clone_data['name'] = auto_vname
clone_data['clone-net-mac-0'] = _get_dhcp_mac_address(auto_vname)
for post in clone_data.keys():
if post.startswith('disk-'):
disk_name = clone_data[post]
if "-" in disk_name:
suffix = disk_name.split("-")[-1]
disk_name = '-'.join((auto_vname, suffix))
else:
suffix = disk_name.split(".")[-1]
disk_name = '.'.join((auto_vname, suffix))
clone_data[post] = disk_name
if not request.user.is_superuser and quota_msg: if not request.user.is_superuser and quota_msg:
msg = _("User %s quota reached, cannot create '%s'!" % (quota_msg, clone_data['name'])) msg = _("User %s quota reached, cannot create '%s'!" % (quota_msg, clone_data['name']))
error_messages.append(msg) error_messages.append(msg)

View file

@ -275,9 +275,9 @@ class wvmInstance(wvmConnect):
device = media.xpath('@device')[0] device = media.xpath('@device')[0]
if device == 'cdrom': if device == 'cdrom':
try: try:
dev = media.xpath('target/@dev') dev = media.xpath('target/@dev')[0]
try: try:
src_fl = media.xpath('source/@file') src_fl = media.xpath('source/@file')[0]
vol = self.get_volume_by_path(src_fl) vol = self.get_volume_by_path(src_fl)
volume = vol.name() volume = vol.name()
stg = vol.storagePoolLookupByVolume() stg = vol.storagePoolLookupByVolume()

View file

@ -133,6 +133,7 @@ LIBVIRT_KEEPALIVE_COUNT = 5
ALLOW_INSTANCE_MULTIPLE_OWNER = True ALLOW_INSTANCE_MULTIPLE_OWNER = True
NEW_USER_DEFAULT_INSTANCES = [] NEW_USER_DEFAULT_INSTANCES = []
CLONE_INSTANCE_DEFAULT_PREFIX = 'instance' CLONE_INSTANCE_DEFAULT_PREFIX = 'instance'
CLONE_INSTANCE_AUTO_NAME = False
LOGS_PER_PAGE = 100 LOGS_PER_PAGE = 100
QUOTA_DEBUG = True QUOTA_DEBUG = True
ALLOW_EMPTY_PASSWORD = True ALLOW_EMPTY_PASSWORD = True