mirror of
https://github.com/retspen/webvirtcloud
synced 2025-02-06 20:45:18 +00:00
Additional changes
This commit is contained in:
parent
e44e01cad4
commit
40738d7920
17 changed files with 289 additions and 19 deletions
|
@ -11,6 +11,9 @@
|
|||
<li class="active">
|
||||
<i class="fa fa-dashboard"></i> {% trans "Overview" %}
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-server"></i> <a href="{% url 'compute_instances' compute.id %}">{% trans "Instances" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
|
||||
</li>
|
||||
|
|
|
@ -1,9 +1,22 @@
|
|||
from django.conf.urls import url
|
||||
from . import views
|
||||
from storages.views import storages, storage
|
||||
from networks.views import networks, network
|
||||
from secrets.views import secrets
|
||||
from create.views import create_instance
|
||||
from interfaces.views import interfaces, interface
|
||||
from computes.views import overview, compute_graph
|
||||
from instances.views import instances
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.computes, name='computes'),
|
||||
url(r'^overview/(?P<compute_id>[0-9]+)/$', views.overview, name='overview'),
|
||||
url(r'^statistics/(?P<compute_id>[0-9]+)/$',
|
||||
views.compute_graph, name='compute_graph'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/$', overview, name='overview'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/statistics$', compute_graph, name='compute_graph'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/instances/$', instances, name='compute_instances'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/storages/$', storages, name='storages'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/storage/(?P<pool>[\w\-\.\/]+)/$', storage, name='storage'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/networks/$', networks, name='networks'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/network/(?P<pool>[\w\-\.]+)/$', network, name='network'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/interfaces/$', interfaces, name='interfaces'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/interface/(?P<iface>[\w\-\.\:]+)/$', interface, name='interface'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/secrets/$', secrets, name='secrets'),
|
||||
url(r'^(?P<compute_id>[0-9]+)/create/$', create_instance, name='create_instance'),
|
||||
]
|
||||
|
|
|
@ -134,6 +134,28 @@ def computes(request):
|
|||
error_messages.append(msg_err.as_text())
|
||||
return render(request, 'computes.html', locals())
|
||||
|
||||
@login_required
|
||||
def compute_instances(request, compute_id):
|
||||
"""
|
||||
:param request:
|
||||
:return:
|
||||
"""
|
||||
if not request.user.is_superuser:
|
||||
return HttpResponseRedirect(reverse('index'))
|
||||
error_messages = []
|
||||
compute = get_object_or_404(Compute, pk=compute_id)
|
||||
try:
|
||||
conn = wvmHostDetails(compute.hostname,
|
||||
compute.login,
|
||||
compute.password,
|
||||
compute.type)
|
||||
hostname, host_arch, host_memory, logical_cpu, model_cpu, uri_conn = conn.get_node_info()
|
||||
hypervisor = conn.hypervisor_type()
|
||||
mem_usage = conn.get_memory_usage()
|
||||
conn.close()
|
||||
except libvirtError as lib_err:
|
||||
error_messages.append(lib_err)
|
||||
return render(request, 'compute_instances.html', locals())
|
||||
|
||||
@login_required
|
||||
def overview(request, compute_id):
|
||||
|
|
|
@ -233,7 +233,7 @@
|
|||
</li>
|
||||
<li>
|
||||
<label for="noVNC_setting_host">Host:</label>
|
||||
<input id="noVNC_setting_host" value="{{ ws_host }}"/>
|
||||
<input id="noVNC_setting_host" value="{{ ws_host }}{{ ws_path }}"/>
|
||||
</li>
|
||||
<li>
|
||||
<label for="noVNC_setting_port">Port:</label>
|
||||
|
|
|
@ -220,6 +220,7 @@
|
|||
//var port = WebUtil.getConfigVar('port', window.location.port);
|
||||
var host = '{{ ws_host }}';
|
||||
var port = '{{ ws_port }}';
|
||||
var wspath = '{{ ws_path }}';
|
||||
|
||||
// if port == 80 (or 443) then it won't be present and should be
|
||||
// set manually
|
||||
|
@ -263,7 +264,7 @@
|
|||
url = 'ws';
|
||||
}
|
||||
|
||||
url += '://' + host;
|
||||
url += '://' + host + wspath;
|
||||
if(port) {
|
||||
url += ':' + port;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ from instances.models import Instance
|
|||
from vrtManager.instance import wvmInstance
|
||||
from webvirtcloud.settings import WS_PORT
|
||||
from webvirtcloud.settings import WS_PUBLIC_HOST
|
||||
from webvirtcloud.settings import WS_PUBLIC_PORT
|
||||
from webvirtcloud.settings import WS_PUBLIC_PATH
|
||||
from libvirt import libvirtError
|
||||
|
||||
|
||||
|
@ -40,8 +42,9 @@ def console(request):
|
|||
console_websocket_port = None
|
||||
console_passwd = None
|
||||
|
||||
ws_port = console_websocket_port if console_websocket_port else WS_PORT
|
||||
ws_port = console_websocket_port if console_websocket_port else WS_PUBLIC_PORT
|
||||
ws_host = WS_PUBLIC_HOST if WS_PUBLIC_HOST else request.get_host()
|
||||
ws_path = WS_PUBLIC_PATH if WS_PUBLIC_PATH else '/'
|
||||
|
||||
if ':' in ws_host:
|
||||
ws_host = re.sub(':[0-9]+', '', ws_host)
|
||||
|
|
199
instances/templates/compute_instances.html
Normal file
199
instances/templates/compute_instances.html
Normal file
|
@ -0,0 +1,199 @@
|
|||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
{% load staticfiles %}
|
||||
{% block title %}{% trans "Instances" %} - {{ compute.name }}{% endblock %}
|
||||
{% block style %}
|
||||
<link rel="stylesheet" href="{% static "css/sortable-theme-bootstrap.css" %}" />
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<!-- Page Heading -->
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
{% if request.user.is_superuser %}
|
||||
{% include 'create_inst_block.html' %}
|
||||
{% endif %}
|
||||
{% if all_host_vms or all_user_vms %}
|
||||
<div class="pull-right search">
|
||||
<input id="filter" class="form-control" type="text" placeholder="Search">
|
||||
</div>
|
||||
{% endif %}
|
||||
<h1 class="page-header">{{ compute.name }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
|
||||
<ol class="breadcrumb">
|
||||
<li class="active">
|
||||
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-server"></i> {% trans "Instances" %}
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-sitemap"></i> <a href="{% url 'networks' compute.id %}">{% trans "Networks" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-wifi"></i> <a href="{% url 'interfaces' compute.id %}">{% trans "Interfaces" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-filter"></i> <a href="{% url 'nwfilters' compute.id %}">{% trans "NWFilters" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-key"></i> <a href="{% url 'secrets' compute.id %}">{% trans "Secrets" %}</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
|
||||
{% include 'errors_block.html' %}
|
||||
<div class="row">
|
||||
{% if not all_host_vms %}
|
||||
<div class="col-lg-12">
|
||||
<div class="alert alert-warning alert-dismissable">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning:" %}</strong> {% trans "Hypervisor doesn't have any instances" %}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="col-lg-12">
|
||||
<table class="table table-hover table-striped sortable-theme-bootstrap" data-sortable>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name<br>Description</th>
|
||||
<th>Host<br>User</th>
|
||||
<th>Status</th>
|
||||
<th>VCPU</th>
|
||||
<th>Memory</th>
|
||||
<th data-sortable="false" style="width:205px;">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="searchable">
|
||||
{% for host, inst in all_host_vms.items %}
|
||||
{% for vm, info in inst.items %}
|
||||
<tr>
|
||||
<td><a href="{% url 'instance' host.0 vm %}">{{ vm }}</a><br><small><em>{{ info.title }}</em></small></td>
|
||||
<td><a href="{% url 'overview' host.0 %}">{{ host.1 }}</a><br><small><em>{% if info.userinstances.count > 0 %}{{ info.userinstances.first_user.user.username }}{% if info.userinstances.count > 1 %} (+{{ info.userinstances.count|add:"-1" }}){% endif %}{% endif %}</em></small></td>
|
||||
<td>
|
||||
{% ifequal info.status 1 %}<span class="text-success">{% trans "Active" %}</span>{% endifequal %}
|
||||
{% ifequal info.status 5 %}<span class="text-danger">{% trans "Off" %}</span>{% endifequal %}
|
||||
{% ifequal info.status 3 %}<span class="text-warning">{% trans "Suspend" %}</span>{% endifequal %}
|
||||
</td>
|
||||
<td>{{ info.vcpu }}</td>
|
||||
<td>{{ info.memory|filesizeformat }}</td>
|
||||
<td><form action="" method="post" role="form">{% csrf_token %}
|
||||
<input type="hidden" name="name" value="{{ vm }}"/>
|
||||
<input type="hidden" name="compute_id" value="{{ host.0 }}"/>
|
||||
{% ifequal info.status 5 %}
|
||||
{% if info.is_template %}
|
||||
<button class="btn btn-sm btn-default" type="button" name="clone" title="{% trans "Clone" %}" onclick="goto_instance_clone({{ host.0 }}, '{{ vm }}');">
|
||||
<span class="glyphicon glyphicon-duplicate"></span>
|
||||
</button>
|
||||
{% else %}
|
||||
<button class="btn btn-sm btn-default" type="submit" name="poweron" title="{% trans "Power On" %}">
|
||||
<span class="glyphicon glyphicon-play"></span>
|
||||
</button>
|
||||
{% endif %}
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "Suspend" %}">
|
||||
<span class="glyphicon glyphicon-pause"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Off" %}">
|
||||
<span class="glyphicon glyphicon-off"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Cycle" %}">
|
||||
<span class="glyphicon glyphicon-refresh"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "VNC Console" %}">
|
||||
<span class="glyphicon glyphicon-eye-open"></span>
|
||||
</button>
|
||||
{% endifequal %}
|
||||
{% ifequal info.status 3 %}
|
||||
<button class="btn btn-sm btn-default" type="submit" name="resume" title="{% trans "Resume" %}">
|
||||
<span class="glyphicon glyphicon-play"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "Suspend" %}">
|
||||
<span class="glyphicon glyphicon-pause"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Off" %}">
|
||||
<span class="glyphicon glyphicon-off"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "Power Cycle" %}">
|
||||
<span class="glyphicon glyphicon-refresh"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "VNC Console" %}">
|
||||
<span class="glyphicon glyphicon-eye-open"></span>
|
||||
</button>
|
||||
{% endifequal %}
|
||||
{% ifequal info.status 1 %}
|
||||
<button class="btn btn-sm btn-default disabled" title="{% trans "Power On" %}">
|
||||
<span class="glyphicon glyphicon-play"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default" type="submit" name="suspend" title="{% trans "Suspend" %}">
|
||||
<span class="glyphicon glyphicon-pause"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default" type="submit" name="poweroff" title="{% trans "Power Off" %}" onclick="return confirm('Are you sure?')">
|
||||
<span class="glyphicon glyphicon-off"></span>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-default" type="submit" name="powercycle" title="{% trans "Power Cycle" %}" onclick="return confirm('Are you sure?')">
|
||||
<span class="glyphicon glyphicon-refresh"></span>
|
||||
</button>
|
||||
<a href="#" class="btn btn-sm btn-default" onclick='open_console("{{ host.0 }}-{{ info.uuid }}")' title="{% trans "Console" %}">
|
||||
<span class="glyphicon glyphicon-eye-open"></span>
|
||||
</a>
|
||||
{% endifequal %}
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block script %}
|
||||
<script src="{% static "js/sortable.min.js" %}"></script>
|
||||
<script>
|
||||
function open_console(uuid) {
|
||||
window.open("{% url 'console' %}?token=" + uuid, "", "width=850,height=485");
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
function filter_table() {
|
||||
var rex = new RegExp($(this).val(), 'i');
|
||||
$('.searchable tr').hide();
|
||||
$('.searchable tr').filter(function () {
|
||||
return rex.test($(this).text());
|
||||
}).show();
|
||||
Cookies.set("instances_filter", $(this).val(), { expires: 1 });
|
||||
}
|
||||
$(document).ready(function () {
|
||||
instances_filter_cookie = Cookies.get("instances_filter");
|
||||
if (instances_filter_cookie) {
|
||||
$('#filter').val(instances_filter_cookie);
|
||||
$('#filter').each(filter_table);
|
||||
}
|
||||
(function ($) {
|
||||
$('#filter').keyup(filter_table)
|
||||
}(jQuery));
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
function goto_instance_clone(compute, instance) {
|
||||
window.location = "/instance/" + compute + "/" + instance + "/#clone";
|
||||
}
|
||||
</script>
|
||||
{% if request.user.is_superuser %}
|
||||
<script>
|
||||
function goto_compute() {
|
||||
var compute = $("#compute_select").val();
|
||||
window.location = "/compute/" + compute + "/create/";
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
{% endblock %}
|
|
@ -15,6 +15,7 @@
|
|||
{% for host, inst in all_host_vms.items %}
|
||||
<tr class="active" style="font-weight: bold;border-bottom: 2px solid darkgray;border-top: 2px solid darkgray;">
|
||||
<td>
|
||||
<span style="text-align:center;">{{ inst.items|length }}</span>
|
||||
<span id="collapse_host_instances_{{ host.1 }}" class="glyphicon glyphicon-chevron-up" onclick="hide_host_instances('{{ host.1 }}');"></span>
|
||||
</td>
|
||||
<td><a href="{% url 'overview' host.0 %}">{{ host.1 }}</a></td>
|
||||
|
|
|
@ -38,7 +38,7 @@ def index(request):
|
|||
|
||||
|
||||
@login_required
|
||||
def instances(request):
|
||||
def instances(request, compute_id=None):
|
||||
"""
|
||||
:param request:
|
||||
:return:
|
||||
|
@ -47,7 +47,11 @@ def instances(request):
|
|||
error_messages = []
|
||||
all_host_vms = {}
|
||||
all_user_vms = {}
|
||||
|
||||
if not compute_id:
|
||||
computes = Compute.objects.all().order_by("name")
|
||||
else:
|
||||
computes = [Compute.objects.get(id=compute_id),]
|
||||
|
||||
def get_userinstances_info(instance):
|
||||
info = {}
|
||||
|
@ -195,8 +199,11 @@ def instances(request):
|
|||
|
||||
view_style = settings.VIEW_INSTANCES_LIST_STYLE
|
||||
|
||||
return render(request, 'instances.html', locals())
|
||||
if compute_id:
|
||||
compute = computes[0]
|
||||
return render(request, 'compute_instances.html', locals())
|
||||
|
||||
return render(request, 'instances.html', locals())
|
||||
|
||||
@login_required
|
||||
def instance(request, compute_id, vname):
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
<li class="active">
|
||||
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
|
||||
</li>
|
||||
<li class="active">
|
||||
<i class="fa fa-server"></i> <a href="{% url 'compute_instances' compute.id %}">{% trans "Instances" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
|
||||
</li>
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
<li class="active">
|
||||
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
|
||||
</li>
|
||||
<li class="active">
|
||||
<i class="fa fa-server"></i> <a href="{% url 'compute_instances' compute.id %}">{% trans "Instances" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
|
||||
</li>
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
<li class="active">
|
||||
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-server"></i> <a href="{% url 'compute_instances' compute.id %}">{% trans "Instances" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
|
||||
</li>
|
||||
|
|
|
@ -10,11 +10,14 @@
|
|||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
{% include 'create_secret_block.html' %}
|
||||
<h1 class="page-header">{% trans "Secrets" %}</h1>
|
||||
<h1 class="page-header">{{ compute.name }}</h1>
|
||||
<ol class="breadcrumb">
|
||||
<li class="active">
|
||||
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
|
||||
</li>
|
||||
<li class="active">
|
||||
<i class="fa fa-server"></i> <a href="{% url 'compute_instances' compute.id %}">{% trans "Instances" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-hdd-o"></i> <a href="{% url 'storages' compute.id %}">{% trans "Storages" %}</a>
|
||||
</li>
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
<p>{% trans "Pool type:" %}</p>
|
||||
<p>{% trans "Pool path:" %}</p>
|
||||
<p>{% trans "Pool status:" %}</p>
|
||||
<p>{% trans "Size:" %} ({{ size|filesizeformat }} / {{ used|filesizeformat }})</p>
|
||||
<p>{% trans "Size:" %} (Used: {{ used|filesizeformat }} / From total: {{ size|filesizeformat }})</p>
|
||||
<p>{% trans "State:" %}</p>
|
||||
<p>{% trans "Autostart:" %}</p>
|
||||
</div>
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
<li class="active">
|
||||
<i class="fa fa-dashboard"></i> <a href="{% url 'overview' compute.id %}">{% trans "Overview" %}</a>
|
||||
</li>
|
||||
<li class="active">
|
||||
<i class="fa fa-server"></i> <a href="{% url 'compute_instances' compute.id %}">{% trans "Instances" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<i class="fa fa-hdd-o"></i> {% trans "Storages" %}
|
||||
</li>
|
||||
|
|
|
@ -8,6 +8,7 @@ from create.views import create_instance
|
|||
from interfaces.views import interfaces, interface
|
||||
from console.views import console
|
||||
from nwfilters.views import nwfilters, nwfilter
|
||||
from computes.views import computes
|
||||
# from django.contrib import admin
|
||||
|
||||
urlpatterns = [
|
||||
|
@ -15,8 +16,13 @@ urlpatterns = [
|
|||
url(r'^instances/$', instances, name='instances'),
|
||||
|
||||
url(r'^instance/', include('instances.urls')),
|
||||
url(r'^instances/$', instances, name='instances'),
|
||||
|
||||
url(r'^accounts/', include('accounts.urls')),
|
||||
|
||||
url(r'^computes/', include('computes.urls')),
|
||||
url(r'^computes/', computes, name='computes'),
|
||||
|
||||
url(r'^logs/', include('logs.urls')),
|
||||
url(r'^datasource/', include('datasource.urls')),
|
||||
|
||||
|
|
Loading…
Reference in a new issue