Mock data are now shared through a service.

This commit is contained in:
Julien Fontanet
2013-11-16 16:35:29 +01:00
parent 8480d1c91f
commit b8bff3e777
11 changed files with 386 additions and 436 deletions

View File

@@ -88,6 +88,8 @@
<!-- build:js({.tmp,app}) scripts/scripts.js -->
<script src="scripts/app.js"></script>
<script src="scripts/filters.js"></script>
<script src="scripts/services.js"></script>
<script src="scripts/controllers/main.js"></script>
<script src="scripts/controllers/nav-bar.js"></script>
<script src="scripts/controllers/list.js"></script>

View File

@@ -6,22 +6,6 @@ angular.module('xoWebApp', [
# 'ngSanitize',
'ui.bootstrap',
])
.filter 'bytes', ->
(size, unit, base) ->
unit ?= 'B'
base ?= 1024
powers = ['', 'K', 'M', 'G', 'T', 'P']
i = 0
while size > base
size /= base
++i
# Maximum 1 decimals.
size = ((size * 10)|0) / 10
return "#{size}#{powers[i]}B"
.config ($routeProvider, $tooltipProvider) ->
$routeProvider
.when '/',

View File

@@ -1,170 +1,5 @@
'use strict'
angular.module('xoWebApp')
.controller 'ListCtrl', ($scope) ->
giga = Math.pow 1024, 3
$scope.objects = [
# Pools.
{
uuid: '843c4b17-7ecf-4102-8696-e0da715e3791'
type: 'pool'
name_label: 'Main pool'
name_description: 'Lorem Ipsum Cloud Dolor'
default_SR: '81e31c8f-9d84-4fa5-b5ff-174e36cc366f'
master: 'b52ebcdb-72e0-45f6-8ec8-2c84ca24d0ec'
HA_enabled: true
hosts: 4
running_hosts: 4
tags: ['Prod', 'Room1']
}
{
uuid: '2d10b0a0-eca4-43a1-8ffb-6266c73280b1'
type: 'pool'
name_label: 'Dev pool'
name_description: 'Dev pool for dev VMs'
#default_SR: null
master: 'ae1a5bac-ac38-4577-bd75-251628549558'
HA_enabled: false
hosts: 4
running_hosts: 3
tags: ['Dev', 'Lab']
}
# Hosts.
{
uuid: 'b52ebcdb-72e0-45f6-8ec8-2c84ca24d0ec'
type: 'host'
name_label: 'Host1'
name_description: 'Prod Host'
pool: '843c4b17-7ecf-4102-8696-e0da715e3791'
power_state: 'Running'
address: '192.168.1.1'
vCPUs: 10
CPUs: 2
memory: {
size: 16 * giga # in bytes
usage: 4 * giga # in bytes
}
running_VMs: 6
tags: ['Prod']
}
{
uuid: 'ae1a5bac-ac38-4577-bd75-251628549558'
type: 'host'
name_label: 'Dev1'
name_description: 'Dev Host for IT'
pool: '2d10b0a0-eca4-43a1-8ffb-6266c73280b1'
power_state: 'Running'
address: '192.168.1.103'
vCPUs: 1
CPUs: 2
memory: {
size: 16 * giga # in bytes
usage: 4 * giga # in bytes
}
running_VMs: 6
tags: ['Dev']
}
# VMs.
{
uuid: '24069f43-0eb1-494a-9911-3b3b371d8b74'
type: 'VM'
name_label: 'VM1'
name_description: 'Default VM for tests'
power_state: 'Running'
address: '192.168.1.42'
vCPUs: 2
memory: {
size: 2 * giga # in bytes
# usage: undefined # in bytes
}
host: 'b52ebcdb-72e0-45f6-8ec8-2c84ca24d0ec'
tags: ['Web', 'Test', 'Debian']
}
{
uuid: 'f6c55ab5-e74e-470f-b928-a2559fcf7f56'
type: 'VM'
name_label: 'VM Dev 2'
name_description: 'Default VM'
power_state: 'Running'
address: '192.168.1.41'
vCPUs: 2
memory: {
size: 2 * giga # in bytes
# usage: undefined # in bytes
}
host: 'b52ebcdb-72e0-45f6-8ec8-2c84ca24d0ec'
#tags: []
}
{
uuid: 'e37e7597-10d7-4bfe-af63-256be1c0a1d1'
type: 'VM'
name_label: 'VFirewall'
name_description: 'Created from template'
power_state: 'Running'
address: '192.168.1.12'
vCPUs: 2
memory: {
size: 4 * giga # in bytes
# usage: undefined # in bytes
}
host: 'b52ebcdb-72e0-45f6-8ec8-2c84ca24d0ec'
#tags: []
}
# SRs.
{
uuid: '81e31c8f-9d84-4fa5-b5ff-174e36cc366f'
type: 'SR'
name_label: 'ZFS1'
name_description: 'Nexenta SAN Storage iSCSI'
size: 100 * giga # in bytes
usage: 10 * giga # in bytes
SR_type: 'LVM'
shared: true
host: 'ae1a5bac-ac38-4577-bd75-251628549558' # host
tags: ['SAN', 'ZFS', 'Nexenta', 'Prod', 'SR']
}
{
uuid: 'ba305307-db94-4f1b-b9fb-dbbbd269cd3d'
type: 'SR'
name_label: 'Local Storage'
name_description: 'Local Disk'
size: 100 * giga # in bytes
usage: 10 * giga # in bytes
SR_type: 'LVM'
shared: false
host: 'b52ebcdb-72e0-45f6-8ec8-2c84ca24d0ec' # host
tags: ['Local', 'SR']
}
{
uuid: 'a86fbb1e-55dd-428e-8154-8bb4f46846d9'
type: 'SR'
name_label: 'ISO SR'
name_description: 'ISO repository'
size: 100 * giga # in bytes
usage: 10 * giga # in bytes
SR_type: 'ISO'
shared: true
host: 'b52ebcdb-72e0-45f6-8ec8-2c84ca24d0ec' # host
tags: ['Local', 'SR']
}
{
uuid: 'e629bc99-ecfe-4c88-b6e8-ee6e33d12f04'
type: 'SR'
name_label: 'Local Storage'
name_description: 'Local Disk'
size: 100 * giga # in bytes
usage: 10 * giga # in bytes
SR_type: 'LVM'
shared: false
host: 'ae1a5bac-ac38-4577-bd75-251628549558' # host
tags: ['Local', 'SR']
}
]
map = {}
map[object.uuid] = object for object in $scope.objects
$scope.map = map
.controller 'ListCtrl', ($scope, objects) ->
$scope.objects = objects.all

View File

@@ -1,199 +1,11 @@
'use strict'
angular.module('xoWebApp')
.controller 'MainCtrl', ($scope, $location) ->
$scope.stats = {
pools: 2
hosts: 4
VMs: 6
running_VMs: 5
vCPUs: 32
CPUs: 12
memory: {
usage: 32 * Math.pow(1024, 3)
size: 64 * Math.pow(1024, 3)
}
}
.controller 'MainCtrl', ($scope, $location, stats, objects) ->
$scope.stats = stats.stats
$scope.goToSR = (uuid) ->
$location.path "/srs/#{uuid}"
$scope.goToVM = (uuid) ->
$location.path "/vms/#{uuid}"
$scope.pools = [
{
uuid: '9baa48dd-162d-4e24-aa8a-52e2b98cc101'
name_label: 'Pool1'
default_SR: '5e0e5191-2ab8-41a0-9699-d3ca26d990ae'
SRs: [
{
uuid: '5e0e5191-2ab8-41a0-9699-d3ca26d990ae'
name_label: 'DataCore'
size: 100 # in bytes
usage: 60 # in bytes
}
{
uuid: '6a858d37-1c8c-4880-9f49-7f792470ceeb'
name_label: 'ZFS'
size: 100 # in bytes
usage: 20 # in bytes
}
]
master: 'b489d3c8-bee2-41ce-9209-d11aaa6be7a1' # XServ1
hosts: [
{
uuid: 'b489d3c8-bee2-41ce-9209-d11aaa6be7a1'
name_label: 'XServ1'
enabled: true
power_state: 'Running'
address: '192.168.1.1'
memory: {
size: 100 # in bytes
usage: 5 # in bytes
}
#VMs: []
}
{
uuid: 'ff2ec5ec-cc58-490c-b3db-c96cb86d814b'
name_label: 'XServ2'
enabled: true
power_state: 'Running'
address: '192.168.1.2'
memory: {
size: 100 # in bytes
usage: 80 # in bytes
}
VMs: [
{
uuid: '1b876103-323d-498b-b5c7-c38f0e4e057b'
name_label: 'Web1'
name_description: 'Apache2 + PHP5 FPM + node VM'
address: '192.168.1.141'
power_state: 'Running'
CPU_usage: 5 # in percentages
memory: {
size: 1024 # in bytes
usage: 599 # in bytes
}
}
{
uuid: 'f3427285-b24d-4ba5-b863-390848bf8321'
name_label: 'Test CentOS'
name_description: 'Testing VM for CentOS 6 Pv Drivers'
#address: ''
power_state: 'Halted'
CPU_usage: 0 # in percentages
memory: {
size: 2048 # in bytes
usage: 599 # in bytes
}
}
{
uuid: '2f590c2b-5a99-454e-987f-4c6beb33e5c8'
name_label: 'Web2'
name_description: 'NGinx FrontEnd'
address: '192.168.1.15'
power_state: 'Unknown'
CPU_usage: 3 # in percentages
memory: {
size: 4096 # in bytes
usage: 599 # in bytes
}
}
{
uuid: 'bd8003d5-f13a-47cd-b571-dff8b80a155b'
name_label: 'PG1 Prod'
name_description: 'Postgres 9.1 VM'
address: '192.168.1.124'
power_state: 'Running'
CPU_usage: 3 # in percentages
memory: {
size: 4096 # in bytes
usage: 599 # in bytes
}
}
{
uuid: '75fc9d5e-f752-43ce-812c-d65c562b0a17'
name_label: 'FreeBSD'
name_description: 'FreeBSD 9 ZFS VM'
address: '192.168.1.171'
power_state: 'Running'
CPU_usage: 85 # in percentages
memory: {
size: 1024 # in bytes
usage: 599 # in bytes
}
}
]
}
]
}
{
uuid: '64d02f09-6663-48e5-8548-63f247e6a9c5'
name_label: 'Dev Pool2'
#SRs: []
master: '5ddbd58d-ff2b-4ab7-a0d2-b8dc3c3609f0' # Host Dev2
hosts: [
{
uuid: 'e04256d8-5ed6-4ea4-8ae0-b836051cfbcb'
name_label: 'Host Dev1'
#enabled: false
power_state: 'Halted'
address: '192.168.1.101'
#memory: {}
#VMs: []
}
{
uuid: '5ddbd58d-ff2b-4ab7-a0d2-b8dc3c3609f0'
name_label: 'Host Dev2'
enabled: true
power_state: 'Running'
address: '192.168.1.102'
memory: {
size: 100 # in bytes
usage: 80 # in bytes
}
VMs: [
{
uuid: '5c794c35-115a-4007-9ad2-ba4950e33dcf'
name_label: 'VDev1'
name_description: 'Dev VM for IT'
address: '192.168.1.241'
power_state: 'Running'
CPU_usage: 30 # in percentages
memory: {
size: 512 # in bytes
usage: 128 # in bytes
}
}
]
}
]
}
]
# Compute additional info.
for pool in $scope.pools
pool.n_hosts = pool.hosts?.length or 0
pool.n_VMs = 0
pool.n_running_VMs = 0
for host in pool.hosts ? []
host.n_VMs = host.VMs?.length ? 0
pool.n_VMs += host.n_VMs
host.n_running_VMs = 0
++host.n_running_VMs for VM in host.VMs ? [] when VM.power_state == 'Running'
pool.n_running_VMs += host.n_running_VMs
# Resolve the pool master.
if host.uuid == pool.master
pool.master = host
# If pool.master.uuid is undefined, we have not resolved the
# master.
pool.master = null unless pool.master.uuid?
$scope.pools = objects.byTypes.pool ? {}
$scope.objects = objects.all
# Sets up the view.
do ->
@@ -208,3 +20,13 @@ angular.module('xoWebApp')
else
--nbChecked
$actionBar.fadeOut 'fast' unless nbChecked
$scope.goToSR = (uuid) ->
$location.path "/srs/#{uuid}"
$scope.goToVM = (uuid) ->
$location.path "/vms/#{uuid}"
$scope.checked_VMs = {}
$scope.selectVMs = ->
$scope.checked_VMs['1b876103-323d-498b-b5c7-c38f0e4e057b'] = true

View File

@@ -1,20 +1,13 @@
'use strict'
angular.module('xoWebApp')
.controller 'NavBarCtrl', ($scope, $location) ->
.controller 'NavBarCtrl', ($scope, $location, session) ->
$scope.login = {
email: 'admin@admin.net'
password: 'admin'
}
$scope.user = null
$scope.ensureListView = ->
$location.path '/list'
$scope.logIn = ->
$scope.user = {
email: $scope.login.email
}
$scope.logOut = ->
$scope.user = null
$scope.session = session

View File

@@ -0,0 +1,33 @@
angular.module('xoWebApp')
# The bytes filters takes a number and formats it using adapted
# units (KB, MB, etc.).
.filter 'bytes', ->
(size, unit, base) ->
unit ?= 'B'
base ?= 1024
powers = ['', 'K', 'M', 'G', 'T', 'P']
i = 0
while size > base
size /= base
++i
# Maximum 1 decimals.
size = ((size * 10)|0) / 10
"#{size}#{powers[i]}B"
# Simply returns the number of elements in the collection.
.filter 'count', ->
(collection) ->
# Array.
if collection.length?
return collection.length
# Object.
count = 0
for key of collection
++count if collection.hasOwnProperty key
count

257
app/scripts/services.coffee Normal file
View File

@@ -0,0 +1,257 @@
angular.module('xoWebApp')
# This service provides session management and inject the `user`
# into the `$rootScope`.
.service 'session', ($rootScope) ->
{
logIn: (email, password) ->
console.log email
$rootScope.user = {
email: email
}
logOut: ->
$rootScope.user = null
}
# This service provides access to XO objects.
.service 'objects', ->
giga = Math.pow 1024, 3
objects = {
# Pools.
'843c4b17-7ecf-4102-8696-e0da715e3791': {
type: 'pool'
name_label: 'Main pool'
name_description: 'Lorem Ipsum Cloud Dolor'
tags: ['Prod', 'Room1']
default_SR: '81e31c8f-9d84-4fa5-b5ff-174e36cc366f'
HA_enabled: true
hosts: [
'b52ebcdb-72e0-45f6-8ec8-2c84ca24d0ec'
]
master: 'b52ebcdb-72e0-45f6-8ec8-2c84ca24d0ec'
}
'2d10b0a0-eca4-43a1-8ffb-6266c73280b1': {
type: 'pool'
name_label: 'Dev pool'
name_description: 'Dev pool for dev VMs'
tags: ['Dev', 'Lab']
#default_SR: null
HA_enabled: false
hosts: [
'ae1a5bac-ac38-4577-bd75-251628549558'
]
master: 'ae1a5bac-ac38-4577-bd75-251628549558'
}
# Hosts
'b52ebcdb-72e0-45f6-8ec8-2c84ca24d0ec': {
type: 'host'
name_label: 'Host1'
name_description: 'Prod Host'
tags: ['Prod']
address: '192.168.1.1'
CPUs: 2
enabled: true
memory: {
size: 16 * giga # in bytes
usage: 4 * giga # in bytes
}
power_state: 'Running'
SRs: [
'ba305307-db94-4f1b-b9fb-dbbbd269cd3d'
'a86fbb1e-55dd-428e-8154-8bb4f46846d9'
]
VMs: [
'24069f43-0eb1-494a-9911-3b3b371d8b74'
'f6c55ab5-e74e-470f-b928-a2559fcf7f56'
'e37e7597-10d7-4bfe-af63-256be1c0a1d1'
]
}
'ae1a5bac-ac38-4577-bd75-251628549558': {
type: 'host'
name_label: 'Dev1'
name_description: 'Dev Host for IT'
tags: ['Dev']
address: '192.168.1.103'
CPUs: 2
enabled: false
memory: {
size: 16 * giga # in bytes
usage: 4 * giga # in bytes
}
power_state: 'Running'
SRs: [
'81e31c8f-9d84-4fa5-b5ff-174e36cc366f'
'e629bc99-ecfe-4c88-b6e8-ee6e33d12f04'
]
#VMs: []
}
# VMs
'24069f43-0eb1-494a-9911-3b3b371d8b74': {
type: 'VM'
name_label: 'VM1'
name_description: 'Default VM for tests'
tags: ['Web', 'Test', 'Debian']
address: '192.168.1.42'
memory: {
size: 2 * giga # in bytes
# usage: undefined # in bytes
}
power_state: 'Running'
CPUs: [
{
usage: 50 # in percentage
}
]
}
'f6c55ab5-e74e-470f-b928-a2559fcf7f56': {
type: 'VM'
name_label: 'VM Dev 2'
name_description: 'Default VM'
#tags: []
address: '192.168.1.41'
memory: {
size: 2 * giga # in bytes
# usage: undefined # in bytes
}
power_state: 'Halted'
CPUs: [
{
usage: 5 # in percentage
}
{
usage: 5 # in percentage
}
]
}
'e37e7597-10d7-4bfe-af63-256be1c0a1d1': {
type: 'VM'
name_label: 'VFirewall'
name_description: 'Created from template'
#tags: []
address: '192.168.1.12'
memory: {
size: 4 * giga # in bytes
# usage: undefined # in bytes
}
power_state: 'Running'
CPUs: [
{
usage: 64 # in percentage
}
{
usage: 99 # in percentage
}
]
}
# SRs
'81e31c8f-9d84-4fa5-b5ff-174e36cc366f': {
type: 'SR'
name_label: 'ZFS1'
name_description: 'Nexenta SAN Storage iSCSI'
tags: ['SAN', 'ZFS', 'Nexenta', 'Prod', 'SR']
shared: true
size: 100 * giga # in bytes
SR_type: 'LVM'
usage: 10 * giga # in bytes
}
'ba305307-db94-4f1b-b9fb-dbbbd269cd3d': {
type: 'SR'
name_label: 'Local Storage'
name_description: 'Local Disk'
tags: ['Local', 'SR']
shared: false
size: 100 * giga # in bytes
SR_type: 'LVM'
usage: 10 * giga # in bytes
}
'a86fbb1e-55dd-428e-8154-8bb4f46846d9': {
type: 'SR'
name_label: 'ISO SR'
name_description: 'ISO repository'
tags: ['Local', 'SR']
shared: true
size: 100 * giga # in bytes
SR_type: 'ISO'
usage: 10 * giga # in bytes
}
'e629bc99-ecfe-4c88-b6e8-ee6e33d12f04': {
type: 'SR'
name_label: 'Local Storage'
name_description: 'Local Disk'
tags: ['Local', 'SR']
shared: false
size: 100 * giga # in bytes
SR_type: 'LVM'
usage: 10 * giga # in bytes
}
}
# Creates a view with objects grouped by type.
byTypes = {}
for uuid, object of objects
{type} = object
(byTypes[type] ?= {})[uuid] = object
# Creates reflexive links & compute additional statistics.
for uuid, VM of byTypes.VM ? []
if VM.CPUs?.length
CPU_usage = 0
for CPU in VM.CPUs ? []
CPU_usage += CPU.usage
VM.$CPU_usage = CPU_usage / VM.CPUs.length
for uuid, host of byTypes.host ? []
running_VMs = []
for VM_uuid in host.VMs ? []
VM = objects[VM_uuid]
VM.$host = uuid
running_VMs.push VM if 'Running' == VM.power_state
host.$running_VMs = running_VMs
for SR_uuid in host.SRs ? []
SR = objects[SR_uuid]
SR.$host = uuid
for uuid, pool of byTypes.pool ? []
running_hosts = []
running_VMs = []
VMs = []
for host_uuid in pool.hosts ? []
host = objects[host_uuid]
host.$pool = uuid
running_hosts.push host if 'Running' == host.power_state
running_VMs.push host.$running_VMs...
VMs.push host.VMs...
pool.$running_hosts = running_hosts
pool.$running_VMs = running_VMs
pool.$VMs = VMs
{
all: objects
byTypes: byTypes
}
.service 'stats', ->
{
stats: {
pools: 2
hosts: 4
VMs: 6
running_VMs: 5
vCPUs: 32
CPUs: 12
memory: {
usage: 32 * Math.pow(1024, 3)
size: 64 * Math.pow(1024, 3)
}
}
}

View File

@@ -103,7 +103,7 @@ td.vm-memory-stat {text-align: right;}
{
background-color: #242628;
border-color: #2e3133;
font-variant:small-caps;
//font-variant:small-caps;
}
.fa {font-variant: normal;}
/* the big subbar */

View File

@@ -2,7 +2,7 @@
<!-- The display depends of the type. -->
<ng-switch
ng-repeat="object in objects | filter:listFilter"
ng-repeat="(uuid, object) in objects | filter:listFilter"
on="object.type"
> <!-- | orderBy:['type', 'name_label'] -->
@@ -27,17 +27,17 @@
<div class="grid-cell flat-cell flat-cell-description">
<i>{{object.name_description}}</i>
</div>
<div class="grid-cell flat-cell" ng-init="default_SR = map[object.default_SR]">
<div class="grid-cell flat-cell" ng-init="default_SR = objects[object.default_SR]">
<div ng-if="default_SR">
Default SR: <a ng-href="#/srs/{{default_SR.uuid}}">{{default_SR.name_label}}</a>.
Default SR: <a ng-href="#/srs/{{object.default_SR}}">{{default_SR.name_label}}</a>.
</div>
<div ng-if="!default_SR">
<em>No default SR.</em>
</div>
</div>
<div class="grid-cell flat-cell" ng-init="master = map[object.master]">
<div class="grid-cell flat-cell" ng-init="master = objects[object.master]">
<div ng-if="!!master">
Master: <a ng-href="#/hosts/{{master.uuid}}">{{master.name_label}}</a>.
Master: <a ng-href="#/hosts/{{object.master}}">{{master.name_label}}</a>.
</div>
<div ng-if="!master">
<em>Unknown master.</em>
@@ -52,7 +52,7 @@
</div>
</div>
<div class="grid-cell flat-cell">
{{object.running_hosts}}/{{object.hosts}} hosts connected.
{{object.$running_hosts.length}}/{{object.hosts.length}} hosts.
</div>
</div>
</div>
@@ -103,13 +103,13 @@
Address: {{object.address}}.
</div>
<div class="grid-cell flat-cell">
{{object.vCPUs}} vCPUs used on {{object.CPUs}} CPUs.
<!--{{object.vCPUs}} vCPUs used on -->{{object.CPUs}} CPUs.
</div>
<div class="grid-cell flat-cell">
{{object.memory.usage | bytes}} used of {{object.memory.size | bytes}} ({{100*object.memory.usage/object.memory.size | number:0}}%).
</div>
<div class="grid-cell flat-cell">
{{object.running_VMs}} VMs runnings.
{{object.$running_VMs.length}}/{{object.VMs.length || 0}} VMs.
</div>
</div>
</div>
@@ -160,13 +160,13 @@
Address: {{object.address}}.
</div>
<div class="grid-cell flat-cell">
{{object.vCPUs}} vCPUs.
{{object.CPUs.length}} vCPUs.
</div>
<div class="grid-cell flat-cell">
{{object.memory.size | bytes}} RAM.
</div>
<div class="grid-cell flat-cell" ng-init="host = map[object.host]; pool = map[host.pool]">
Resident on: <a ng-href="#/hosts/{{host.uuid}}">{{host.name_label}}</a> (<a ng-href="#/pools/{{pool.uuid}}">{{pool.name_label}}</a>).
<div class="grid-cell flat-cell" ng-init="host = objects[object.$host]; pool = objects[host.$pool]">
Resident on: <a ng-href="#/hosts/{{object.$host}}">{{host.name_label}}</a> (<a ng-href="#/pools/{{host.$pool}}">{{pool.name_label}}</a>).
</div>
</div>
</div>
@@ -219,12 +219,12 @@
<div class="grid-cell flat-cell">
Type: {{object.SR_type}}.
</div>
<div class="grid-cell flat-cell" ng-init="host = map[object.host]; pool = map[host.pool]">
<div class="grid-cell flat-cell" ng-init="host = objects[object.$host]; pool = objects[host.$pool]">
<div ng-if="object.shared">
<strong>Shared on <a ng-href="#/pools/{{pool.uuid}}">{{pool.name_label}}</a>.</strong>
<strong>Shared on <a ng-href="#/pools/{{host.$pool}}">{{pool.name_label}}</a>.</strong>
</div>
<div ng-if="!object.shared">
Connected to <a ng-href="#/hosts/{{host.uuid}}">{{host.name_label}}</a>.
Connected to <a ng-href="#/hosts/{{object.$host}}">{{host.name_label}}</a>.
</div>
</div>
</div>

View File

@@ -30,14 +30,19 @@
<div class="grid-cell">
<div class="btn-group before-action-bar">
<a type="button" class="btn navbar-btn btn-default dropdown-toggle inversed">
<input type="checkbox" class="inverse">
<input
type="checkbox"
class="inverse"
ng-click="$event.stopPropagation()"
ng-changed="selectVMs()"
/>
<i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu inverse" role="menu">
<li><a href="#">All</a></li>
<li><a href="#">On host1</a></li>
<li><a href="#">On host2</a></li>
<li><a href="#">On host3</a></li>
<li><a ng-click="selectVMs()">All</a></li>
<li ng-repeat="host in hosts">
<a ng-click="selectVMs({host: host.uuid})">{{host.name_label}}</a>
</li>
</ul>
</div>
<div class="action-bar">
@@ -66,14 +71,14 @@
<div style="margin-top: 50px; visibility: hidden; height: 0">.</div>
<!-- Contains a pool and all its children (hosts). -->
<div ng-repeat="pool in pools" class="grid pool-block">
<div ng-repeat="(uuid, pool) in pools" class="grid pool-block">
<!-- Contains information about the pool. -->
<div class="grid-cell grid--gutters pool-cell">
<!-- Header (name + dropdown menu). -->
<div class="dropdown dropdown-pool">
<a class="pool-name" ng-href="#/pools/{{pool.uuid}}">
<a class="pool-name" ng-href="#/pools/{{uuid}}">
{{pool.name_label}}
</a>
<a class="dropdown-toggle">&nbsp;<i class="fa fa-caret-down big-caret"></i>&nbsp;</a>
@@ -93,24 +98,24 @@
<!-- Stats. -->
<ul class="list-unstyled stats">
<li>
<i tooltip="{{pool.n_hosts}} hosts connected">
<i class="small">{{pool.n_hosts}}x</i>
<i tooltip="{{pool.hosts.length}} hosts connected">
<i class="small">{{pool.hosts.length}}x</i>
<i class="xo-icon-host"></i>
</i>
&nbsp;
<i tooltip="{{pool.n_running_VMs}} of {{pool.n_VMs}} VMs running">
<i class="small">{{pool.n_running_VMs}}x</i>
<i tooltip="{{pool.$running_VMs.length}} of {{pool.$VMs.length}} VMs running">
<i class="small">{{pool.$running_VMs.length}}x</i>
<i class="xo-icon-console"></i>
</i>
</li>
<li ng-if="pool.master">
Master: <a href="#/hosts/{{pool.master.uuid}}">{{pool.master.name_label}}</a>
Master: <a href="#/hosts/{{pool.master}}">{{objects[pool.master].name_label}}</a>
</li>
<li ng-if="!pool.master">No master</li>
</ul>
<!-- /Stats. -->
<!-- SRs. -->
<!-- TODOs: SRs. -->
<p ng-if="pool.SRs" class="center small-caps">Shared SR:</p>
<table ng-if="pool.SRs" class="table table-hover table-condensed">
<tr ng-repeat="SR in pool.SRs" ng-click="goToSR(SR.uuid)">
@@ -148,14 +153,18 @@
<div class="grid-cell grid--gutters hosts-vms-cells">
<!-- Contains a host and all its children (VMs). -->
<div ng-repeat="host in pool.hosts" class="grid">
<div
ng-repeat="uuid in pool.hosts"
ng-init="host = objects[uuid]"
class="grid"
>
<!-- Contains information about the host. -->
<div class="grid-cell host-cell">
<!-- Header (name + dropdown menu). -->
<div class="dropdown dropdown-pool">
<a class="host-name" ng-href="#/hosts/{{host.uuid}}">
<a class="host-name" ng-href="#/hosts/{{uuid}}">
{{host.name_label}}
</a>
<a class="dropdown-toggle">&nbsp;<i class="fa fa-caret-down"></i>&nbsp;</a>
@@ -173,12 +182,15 @@
<!-- Stats. -->
<ul class="list-unstyled stats">
<!-- Warning icon if host disabled -->
<li ng-if="!host.enabled">
<i class="fa fa-warning text-danger"></i>
<!-- Warning icon if host is halted or disabled -->
<li ng-if="'Halted' === host.power_state" class="text-danger">
<i class="fa fa-warning"></i> Halted
</li>
<li ng-if="'Halted' !== host.power_state &amp;&amp; !host.enabled" class="text-warning">
<i class="fa fa-warning"></i> Disabled
</li>
<!-- Memory -->
<li ng-if="host.power_state == 'Running'">
<li ng-if="host.power_state === 'Running'">
<i class="xo-icon-memory i-progress"></i>
<div
class="progress progress-small"
@@ -206,31 +218,43 @@
<!-- Contains all the VMs of this pool. -->
<div class="grid grid-cell vm-cell">
<p ng-if="!host.enabled &amp;&amp; host.power_state == 'Running'" class="vms-notice">
Host disabled.
</p>
<!-- If no VMs, fill the space with a message. -->
<div ng-if="!host.VMs.length" class="vms-notice">
<p ng-if="host.power_state == 'Halted'" class="vms-notice">
Host disconnected.
</p>
<p ng-if="'Halted' === host.power_state">
Host halted.
</p>
<p ng-if="host.enabled &amp;&amp; !host.VMs" class="vms-notice">
No VMs on this host.
</p>
<div ng-if="'Halted' !== host.power_state">
<p ng-if="!host.enabled">
Host disabled.
</p>
<p ng-if="host.enabled">
No VMs on this host.
</p>
</div>
</div>
<!-- /Message if no VMs. -->
<!-- TODO: comment -->
<div class="table-responsive">
<table ng-if="host.VMs" class="table table-hover table-condensed">
<table ng-if="host.VMs.length" class="table table-hover table-condensed">
<!-- Contains a VM. -->
<tr ng-repeat="VM in host.VMs" ng-click="goToVM(VM.uuid)">
<tr
ng-repeat="uuid in host.VMs"
ng-init="VM = objects[uuid]"
ng-click="goToVM(uuid)"
>
<!-- Handle used for drag & drop. -->
<td class="grab"></td>
<!-- Checkbox used for selection. -->
<td class="select-vm">
<input type="checkbox" class="checkbox-vm"/>
<input type="checkbox" ng-checked="checked_VMs[VM.uuid]" />
</td>
<!-- Power state -->
@@ -271,11 +295,11 @@
<!-- CPU -->
<td class="vm-cpu-stat col-md-1">
<div ng-if="VM.power_state == 'Running'" class="cpu" tooltip="CPU Load: {{VM.CPU_usage}}%">
<div ng-if="VM.power_state == 'Running'" class="cpu" tooltip="CPU Load: {{VM.$CPU_usage}}%">
<!-- @TODO: include logic elsewhere + icon class in sass -->
<i ng-if="VM.CPU_usage < 25" class="fa fa-dashboard text-success"></i>
<i ng-if="VM.CPU_usage >= 25 &amp;&amp; VM.CPU_usage <= 80" class="fa fa-dashboard text-warning"></i>
<i ng-if="VM.CPU_usage >80" class="fa fa-dashboard text-danger"></i>
<i ng-if="VM.$CPU_usage < 25" class="fa fa-dashboard text-success"></i>
<i ng-if="VM.$CPU_usage >= 25 &amp;&amp; VM.$CPU_usage <= 80" class="fa fa-dashboard text-warning"></i>
<i ng-if="VM.$CPU_usage >80" class="fa fa-dashboard text-danger"></i>
</div>
</td>

View File

@@ -98,7 +98,7 @@
<!-- Displayed only when the user is connected. -->
<li ng-if="user"><a><i class="fa fa-user"></i> {{user.email}}</a></li>
<li ng-if="user"><a ng-click="logOut()"><i class="fa fa-sign-out"></i></a></li>
<li ng-if="user"><a ng-click="session.logOut()"><i class="fa fa-sign-out"></i></a></li>
<!-- /When user is connected. -->
<!-- Displayed only when the user is not connected. -->
@@ -110,7 +110,7 @@
<form
class="dropdown-menu login-form-dark"
ng-submit="logIn()"
ng-submit="session.logIn(login.email, login.password)"
ng-click="$event.stopPropagation()"
>