This commit is contained in:
Julien Fontanet 2013-07-22 14:20:45 +02:00
parent a4039e99c1
commit 82b645cf61
2 changed files with 380 additions and 33 deletions

View File

@ -241,7 +241,7 @@
</script>
<!-- Hosts list. -->
<script type="text/template" id="tpl-hosts-list">
<script type="text/template" id="tpl-hosts-list" data-class="container">
<h3 class="center"><%= link(name, ['pools', id]) %></h3>
<table class="table table-bordered table-hover table-striped">
@ -255,14 +255,230 @@
<tbody></tbody>
</table>
</script>
<script type="text/template" id="tpl-hosts-list-item">
<td><%= link(name, ['servers', id]) %></td>
<script type="text/template" id="tpl-hosts-list-item" data-tag="tr">
<td><%= link(name, ['hosts', id]) %></td>
<td><%= description %></td>
<td><%= progressBar(- 100 * memory.free / memory.total) %></td>
<td><%= IPs.length ? IPs.join(', ') : '<i>none</i>' %></td><!-- @todo -->
<td><%= formatDuration_fromNow(start_time) %></td>
</script>
<script type="text/template" id="tpl-host" data-class="container well">
<h3 class="center"><%= name %></h3>
<!-- Tabs menu. -->
<ul class="nav nav-tabs">
<li class="active"><a href="#general"><i class="icon-home"></i> General</a></li>
<li><a href="#memory"><i class="icon-tasks"></i> Memory</a></li>
<li><a href="#storage"><i class="icon-hdd"></i> Storage</a></li>
<li><a href="#network"><i class="icon-sitemap"></i> Network</a></li>
<!-- @todo
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="icon-cog"></i> Misc <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="#console"><i class="icon-desktop"></i> Console</a></li>
<li><a href="#perfs"><i class="icon-bar-chart"></i> Perfs</a></li>
<li><a href="#alerts"><i class="icon-bullhorn"></i> Alerts</a></li>
<li><a href="#logs"><i class="icon-comment"></i> Logs</a></li>
<li><a href="#other"><i class="icon-asterisk"></i> Other</a></li>
</ul>
</li> -->
</ul>
<div class="tab-content"></ul>
</script>
<script type="text/template" id="tpl-host-general" data-class="tab-pane fade in active" data-id="general">
<dl class="dl-horizontal">
<dt>Name:</dt><dd><%= name %></dd>
<dt>Description:</dt><dd><%= description %></dd>
<dt>Pool master:</dt><dd><%= yesNo(is_pool_master) %></dd>
<dt>Enabled:</dt><dd><%= yesNo(enabled) %></dd>
<dt>iSCSI IQN:</dt><dd><%= iscsi_iqn || '<i>none</i>' %></dd>
<dt>OS:</dt><dd><%= os_version || '<i>none</i>' %></dd>
<dt>Log destination:</dt><dd><%= log_destination %></dd>
<dt>Server uptime:</dt><dd><%= start_time ? formatDuration_fromNow(start_time) : '<i>N/A</i>' %></dd>
<dt>Toolstack uptime:</dt><dd><%= tool_stack_start_time ? formatDuration_fromNow(tool_stack_start_time) : '<i>N/A</i>' %></dd>
<dt>UUID:</dt><dd><%= uuid %></dd>
</dl>
<dl class="dl-horizontal">
<dt>Hostname:</dt><dd><%= hostname %></dd>
<% for (var i = 0; i < PIFs.length; ++i)
{
var PIF = PIFs[i];
%><dt><%= PIF.name %></dt><dd><%= PIF.IP || '<i>no address</i>' %></dd><%
} %>
</dl>
<dl class="dl-horizontal">
<dt>XCP version:</dt><dd><%= software_version.platform_version %></dd>
</dl>
<dl class="dl-horizontal">
<% for (var i = 0; i < CPUs.length; ++i)
{
var CPU = CPUs[i];
%><dt>CPU #<%= i + 1 %>:</dt>
<dd>
<%= CPU.number %>×
<%= CPU.vendor %>
<%= CPU.model_name %>
<%= CPU.model %>
@ <%= CPU.speed %>
<%= CPU.vendor %>
</dd><%
} %>
</dl>
</script>
<script type="text/template" id="tpl-host-memory" data-class="tab-pane fade" data-id="memory">
<div class="progress progress-big progress-danger">
<%
var size_per_VM = _.clone(memory.per_VM);
size_per_VM.free = memory.free;
size_per_VM = xo.plop(size_per_VM, 0.5, 100);
for (var VM_uuid in memory.per_VM)
{
var VM = VMs[VM_uuid];
var VM_mem = formatSize(memory.per_VM[VM_uuid]);
var size = size_per_VM[VM_uuid];
if ('dom0' === VM_uuid )
{
%><div class="bar bar-info" style="width: <%= size %>%;">
<%= VM.name %><br/>
(<%= VM_mem %>)
</div><%
}
else
{
%><div class="bar" style="width: <%= size %>%;">
<%= link(VM.name, ['vms', VM_uuid]) %><br/>
(<%= VM_mem %>)
</div><%
}
} %>
</div>
<dl class="dl-horizontal">
<dt>Total memory:</dt><dd><%= formatSize(memory.total) %></dd>
<dt>Currently used:</dt><dd><%= formatSize(memory.total-memory.free) %></dd>
<dt>Available memory:</dt><dd><%= formatSize(memory.free) %></dd>
</dl>
</script>
<script type="text/template" id="tpl-host-storage" data-class="tab-pane fade" data-id="storage">
<table class="table table-hover table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Type</th>
<th>Shared</th>
<th>Usage</th>
<th>Size</th>
<th>Allocated</th>
</tr>
</thead>
<tbody>
<% for (var i = 0; i < SRs.length; ++i)
{
var SR = SRs[i];
%><tr>
<td><i class="icon-hdd"></i> <%= SR.name %></td>
<td><%= SR.description %></td>
<td><%= SR.type %></td>
<td><%= SR.shared ? 'Yes' : 'No' %></td>
<td><%= Math.round(100*SR.used/SR.total) %>% (<%= formatSize(SR.used) %> used)</td>
<td><%= formatSize(SR.total) %></td>
<td><%= formatSize(SR.allocated) %></td>
</tr><%
} %>
</tbody>
</table>
</script>
<script type="text/template" id="tpl-host-network" data-class="tab-pane fade" data-id="network">
<table class="table table-hover table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Speed</th>
<th>Duplex</th>
<th>IP</th>
<th>MAC</th>
<th>Hardware</th>
<th>Link status</th>
</tr>
</thead>
<tbody>
<% for (var i = 0; i < PIFs.length; ++i)
{
var PIF = PIFs[i];
%><tr>
<td><i class="icon-sitemap"></i> <%= PIF.name %></td>
<td><%= PIF.speed %></td>
<td><%= PIF.duplex ? 'Yes' : 'No' %></td>
<td><%= PIF.IP ? PIF.IP : '<i>none</i>' %></td>
<td class="mac-address"><%= PIF.MAC %></td>
<td><%= PIF.vendor %> <%= PIF.device %></td>
<td><%
if (PIF.currently_attached)
{
%><span class="label label-success">Connected</span></td><%
}
else
{
%><span class="label label-important">Not connected</span></td><%
} %>
</tr><%
} %>
</tbody>
</table>
</script>
<!-- <script type="text/template" id="tpl-host-console" data-class="tab-pane fade" data-id="console">
@todo
</script> -->
<!-- <script type="text/template" id="tpl-host-perfs" data-class="tab-pane fade" data-id="perfs">
@todo
</script> -->
<!-- <script type="text/template" id="tpl-host-alert" data-class="tab-pane fade" data-id="alert">
@todo
</script> -->
<!-- <script type="text/template" id="tpl-host-other" data-class="tab-pane fade" data-id="other">
@todo
<dl class="dl-horizontal">
<dt>Multipathing:</dt>
<dd>None</dd>
<dt>Log destination:</dt>
<dd>Local</dd>
<dt>Power On:</dt>
<dd>Disabled</dd>
</dl>
</script> -->
<!-- <script type="text/template" id="tpl-host-logs" data-class="tab-pane fade" data-id="logs">
@todo
<table class="table table-hover table-condensed">
<thead>
<tr>
<th>Event name</th>
<th>Details</th>
<th>Date</th>
<th>Time</th>
</tr>
</thead>
<tbody>
<tr>
<td><i class="icon-comment"></i> Shutting down</td>
<td>User canceled</td>
<td>15.3.2011 18:29:34</td>
<td>00:10:16</td>
</tr>
<tr>
<td><i class="icon-comment"></i> Shutting down</td>
<td>User canceled</td>
<td>15.3.2011 18:29:22</td>
<td>00:10:16</td>
</tr>
</tbody>
</table>
</script> -->
<!-- VMs list. -->
<script type="text/template" id="tpl-vms-list">
<h3 class="center"><%= name %></h3>
@ -282,7 +498,7 @@
<tbody></tbody>
</table>
</script>
<script type="text/template" id="tpl-vms-list-item">
<script type="text/template" id="tpl-vms-list-item" data-tag="tr">
<% var usage = 100 - Math.round(100*memory.free/memory.total) %>
<td><%= link(name, ['vms', id]) %></td>
@ -303,6 +519,7 @@
<script src="http://marionettejs.com/downloads/backbone.marionette.js"></script>
<script src="./js/moment.js"></script>
<script src="./js/bootstrap.js"></script>
<script src="./js/xo.helpers.js"></script>
<script src="./js/xo.js"></script>
</body>

View File

@ -265,26 +265,72 @@
*
* @todo Documentation
*
* @param {integer} percentage [description]
* @param {array} bars [description]
* @param {object=} options [description]
*
* @return string
*/
'progressBar': function (percentage, options) {
percentage = Math.round(percentage);
if (percentage < 0)
'progressBar': function (bars, options) {
/* jshint laxbreak:true */
var has_labels = false;
// Normalizes bars.
if (!_.isArray(bars))
{
percentage += 100;
bars = [bars];
}
_.each(bars, function (bar, i) {
if (_.isNumber(bar))
{
bars[i] = bar = {
'value': bar
};
}
var label = (options && options.label) || (percentage +'%');
if ((bar.value = Math.round(bar.value)) < 0)
{
bar.value += 100;
}
return [
'<div class="progress progress-info progress-small" ',
'title="'+ label +'">',
'<div class="bar" style="width:'+ percentage +'%"></div>',
'</div>',
].join('');
has_labels = has_labels || !!bar.label;
_.defaults(bar, {
'color': 'info',
'title': bar.value +'%',
'label': '',
});
});
// Normalizes global options.
if (!options)
{
options = {};
}
has_labels = has_labels || !!options.label;
_.defaults(options, {
'size': has_labels ? 'normal' : 'small',
'title': (1 === bars.length) ? bars[0].title : '',
});
console.log(options);
// HTML generation.
var html = [
'<div class="progress',
(options.size in {'small':0, 'big':0}) // @todo Ugly.
? ' progress-'+ options.size
: '',
'" title="', options.title, '">'];
_.each(bars, function (bar) {
html.push(
'<div class="bar bar-', bar.color, '" title="', bar.title,
'" style="width: ', bar.value, '%">', bar.label, '</div>'
);
});
html.push(options.label, '</div>');
return html.join('');
},
/**
@ -311,6 +357,19 @@
'</span>',
].join('');
},
/**
* [description]
*
* @todo Documentation
*
* @param {boolean} truth [description]
*
* @return string
*/
'yesNo': function (truth) {
return (truth ? 'Yes' : 'No');
},
};
//////////////////////////////////////////////////////////////////
@ -398,17 +457,43 @@
};
}();
var ItemView = Backbone.Marionette.ItemView.extend({
'templateHelpers': template_helpers,
var _constructor = function (super_constructor) {
return function (options) {
// Classes and id can be defined directly in the template element.
var tpl = options.template || this.template;
if (tpl)
{
var val;
var $tpl = $(tpl);
'constructor': function () {
Backbone.Marionette.ItemView.apply(this, arguments);
if (!options.id && (val = $tpl.attr('data-id')))
{
options.id = val;
}
if (!options.tagName && (val = $tpl.attr('data-tag')))
{
options.tagName = val;
}
if (!options.className && (val = $tpl.attr('data-class')))
{
options.className = val;
}
}
if (this.model)
super_constructor.apply(this, arguments);
// Re-render when the model changes.
if (this.model && (false !== this.listenToModelChange))
{
this.listenTo(this.model, 'change', this.render);
}
},
};
};
var ItemView = Backbone.Marionette.ItemView.extend({
'templateHelpers': template_helpers,
'constructor': _constructor(Backbone.Marionette.ItemView),
'serializeData': _serializeData,
});
@ -416,14 +501,15 @@
var CompositeView = Backbone.Marionette.CompositeView.extend({
'templateHelpers': template_helpers,
'constructor': function () {
Backbone.Marionette.CompositeView.apply(this, arguments);
'constructor': _constructor(Backbone.Marionette.CompositeView),
if (this.model)
{
this.listenTo(this.model, 'change', this.render);
}
},
'serializeData': _serializeData,
});
var LayoutView = Backbone.Marionette.Layout.extend({
'template_helpers': template_helpers,
'constructor': _constructor(Backbone.Marionette.Layout),
'serializeData': _serializeData,
});
@ -436,13 +522,13 @@
'template': '#tpl-stats',
});
//----------------------------------------------------------------
var HostsListItemView = ItemView.extend({
'template': '#tpl-hosts-list-item',
'tagName': 'tr',
});
var HostsListView = CompositeView.extend({
'template': '#tpl-hosts-list',
'className': 'container',
'itemView': HostsListItemView,
'itemViewContainer': 'tbody',
@ -455,9 +541,46 @@
'itemView': HostsListView,
});
//----------------------------------------------------------------
var HostView = CompositeView.extend({
'template': '#tpl-host',
'itemView': ItemView,
'itemViewOptions': function (model) {
return {
'model': this.model,
'template': model.get('template'),
};
},
'itemViewContainer': '.tab-content',
'events': {
'click .nav-tabs a': function (e) {
e.preventDefault();
$(e.target).tab('show');
},
},
'listenToModelChange': false,
'initialize': function () {
this.collection = new Backbone.Collection([
{'template': '#tpl-host-general'},
{'template': '#tpl-host-memory'},
{'template': '#tpl-host-storage'},
{'template': '#tpl-host-network'},
]);
// Only re-render on name change.
// @todo Find a cleaner way.
this.listenTo(this.model, 'change:name', this.render);
},
});
//----------------------------------------------------------------
// var VMsListItemView = ItemView.extend({
// 'template': '#tpl-vms-list-item',
// 'tagName': 'tr',
// });
// var VMsListView = CompositeView.extend({
// 'template': '#tpl-vms-list',
@ -478,7 +601,7 @@
'': 'home',
'hosts': 'hosts_listing',
// 'hosts/:id': 'host_show',
'hosts/:id': 'host_show',
// //'hosts/:id/edit': 'host_edit',
// 'networks': 'networks_listing',
@ -578,6 +701,13 @@
}));
},
'host_show': function (id) {
var host = new Host({"CPUs":[],"control_domain":"cfd988d7-97a5-4d9e-9409-20853c74ac1f","description":"Default install of XenServer","enabled":true,"hostname":"andromeda","is_pool_master":false,"iscsi_iqn":null,"log_destination":"local","memory":{"free":"8057126912","total":"17143996416","per_VM":{"dom0":"777256960","ae0a235b-b5e5-105c-ed21-f97198cf1751":"2147483648","2f1647cf-54b8-9ee1-fb90-404680f25364":"3145728000","e87afeff-5921-116f-ec91-d772487ac5fe":"536870912","3ff02693-c481-3334-5676-5b74c684092f":"2147483648"}},"name":"andromeda","os_version":null,"PIFs":[{"currently_attached":true,"device":"82574L Gigabit Network Connection","duplex":false,"IP":"","MAC":"e4:11:5b:b7:f3:8f","name":"PIF #0","speed":"0","uuid":"e03acef7-2347-2c09-e6a8-9026e065cfcf","vendor":"Intel Corporation"},{"currently_attached":true,"device":"82574L Gigabit Network Connection","duplex":true,"IP":"88.190.41.127","MAC":"e4:11:5b:b7:f3:8e","name":"PIF #1","speed":"1000","uuid":"b190509e-6bf0-7306-0347-fa6932184853","vendor":"Intel Corporation"}],"SRs":[{"allocated":"0","description":"XenServer Tools ISOs","name":"XenServer Tools","shared":true,"total":"-1","type":"iso","used":"-1"},{"allocated":"0","description":"","name":"LocalISO","shared":false,"total":"-1","type":"iso","used":"-1"},{"allocated":"640289865728","description":"","name":"Local storage","shared":false,"total":"1991761723392","type":"lvm","used":"651002118144"},{"allocated":"0","description":"","name":"Removable storage","shared":false,"total":"0","type":"udev","used":"0"},{"allocated":"0","description":"Physical DVD drives","name":"DVD drives","shared":false,"total":"0","type":"udev","used":"0"}],"start_time":0,"tool_stack_start_time":0,"uuid":"1038e558-ce82-42d8-bf94-5c030cbeacd6","software_version":{"product_version":"6.2.0","product_version_text":"6.2","product_version_text_short":"6.2","platform_name":"XCP","platform_version":"1.8.0","product_brand":"XenServer","build_number":"70446c","hostname":"othone-2","date":"2013-06-14","dbv":"2013.0621","xapi":"1.3","xen":"4.1.5","linux":"2.6.32.43-0.4.1.xs1.8.0.835.170778xen","xencenter_min":"2.0","xencenter_max":"2.0","network_backend":"openvswitch","xs:xenserver-transfer-vm":"XenServer Transfer VM, version 6.2.0, build 70314c","xcp:main":"Base Pack, version 1.8.0, build 70446c","xs:main":"XenServer Pack, version 6.2.0, build 70446c"},"VMs":{"dom0":{"name":"Dom0"},"ae0a235b-b5e5-105c-ed21-f97198cf1751":{"name":"ald"},"2f1647cf-54b8-9ee1-fb90-404680f25364":{"name":"web1"},"e87afeff-5921-116f-ec91-d772487ac5fe":{"name":"shelter"},"3ff02693-c481-3334-5676-5b74c684092f":{"name":"cloud"}}});
// @todo Gets data from XO-Server.
app.main.show(new HostView({'model': host}));
},
'not_found': function (path) {
alert('no such page: '+ path);
this.navigate('', {'trigger': true});