Initial version based on Backbone.js & Marionette.js.
This commit is contained in:
parent
850cf95d3b
commit
a4039e99c1
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,5 +1,2 @@
|
||||
/config/local.php
|
||||
/log
|
||||
/vendor/
|
||||
/cache/
|
||||
*~
|
||||
|
@ -1,21 +0,0 @@
|
||||
{
|
||||
"name": "vates/xo-web",
|
||||
"description": "Xen Orchestra web client.",
|
||||
"license": "GPL-3.0",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Olivier Lambert",
|
||||
"email": "olivier.lambert@vates.fr"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"monolog/monolog": "~1.2",
|
||||
"vates/gallic": "dev-master",
|
||||
"vates/xo-lib": "dev-master",
|
||||
"vates/switchman": "dev-master"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": { "": "lib" }
|
||||
}
|
||||
}
|
251
composer.lock
generated
251
composer.lock
generated
@ -1,251 +0,0 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
|
||||
],
|
||||
"hash": "0713d6b8e361bea4434262e9caf28900",
|
||||
"packages": [
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "1.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Seldaek/monolog.git",
|
||||
"reference": "1.4.1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/1.4.1",
|
||||
"reference": "1.4.1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"psr/log": ">=1.0,<2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/couchdb": "dev-master",
|
||||
"mlehner/gelf-php": "1.0.*",
|
||||
"raven/raven": "0.3.*"
|
||||
},
|
||||
"suggest": {
|
||||
"doctrine/couchdb": "Allow sending log messages to a CouchDB server",
|
||||
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
|
||||
"ext-mongo": "Allow sending log messages to a MongoDB server",
|
||||
"mlehner/gelf-php": "Allow sending log messages to a GrayLog2 server",
|
||||
"raven/raven": "Allow sending log messages to a Sentry server"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.4.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Monolog": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Sends your logs to files, sockets, inboxes, databases and various web services",
|
||||
"homepage": "http://github.com/Seldaek/monolog",
|
||||
"keywords": [
|
||||
"log",
|
||||
"logging",
|
||||
"psr-3"
|
||||
],
|
||||
"time": "2013-04-01 10:04:58"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
"version": "1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/log",
|
||||
"reference": "1.0.0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://github.com/php-fig/log/archive/1.0.0.zip",
|
||||
"reference": "1.0.0",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Psr\\Log\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for logging libraries",
|
||||
"keywords": [
|
||||
"log",
|
||||
"psr",
|
||||
"psr-3"
|
||||
],
|
||||
"time": "2012-12-21 11:40:51"
|
||||
},
|
||||
{
|
||||
"name": "vates/gallic",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/julien-f/gallic.git",
|
||||
"reference": "c7582371098af573c51572cee87f92e470a753c8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/julien-f/gallic/zipball/c7582371098af573c51572cee87f92e470a753c8",
|
||||
"reference": "c7582371098af573c51572cee87f92e470a753c8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/Gallic.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"GPL-3.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Julien Fontanet",
|
||||
"email": "julien.fontanet@vates.fr"
|
||||
}
|
||||
],
|
||||
"description": "PHP Library.",
|
||||
"keywords": [
|
||||
"autoloading",
|
||||
"object storage",
|
||||
"templating"
|
||||
],
|
||||
"time": "2013-03-29 12:37:25"
|
||||
},
|
||||
{
|
||||
"name": "vates/switchman",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/vatesfr/switchman.git",
|
||||
"reference": "3e70919916f7fad6ab338e06876deea7d482d873"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/vatesfr/switchman/zipball/3e70919916f7fad6ab338e06876deea7d482d873",
|
||||
"reference": "3e70919916f7fad6ab338e06876deea7d482d873",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": ">=3.7,<3.8"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Switchman": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"GPL-3.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Julien Fontanet",
|
||||
"email": "julien.fontanet@vates.fr"
|
||||
}
|
||||
],
|
||||
"description": "Route matching library.",
|
||||
"keywords": [
|
||||
"route matching",
|
||||
"routing"
|
||||
],
|
||||
"time": "2013-04-11 13:01:26"
|
||||
},
|
||||
{
|
||||
"name": "vates/xo-lib",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/vatesfr/xo-lib.git",
|
||||
"reference": "965044c019b622330421ae856ac57fef1afbc4ab"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/vatesfr/xo-lib/zipball/965044c019b622330421ae856ac57fef1afbc4ab",
|
||||
"reference": "965044c019b622330421ae856ac57fef1afbc4ab",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"GPL-3.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Julien Fontanet",
|
||||
"email": "julien.fontanet@vates.fr"
|
||||
}
|
||||
],
|
||||
"description": "Xen Orchestra client library.",
|
||||
"keywords": [
|
||||
"xen",
|
||||
"xen-orchestra"
|
||||
],
|
||||
"time": "2013-02-08 14:26:07"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
||||
],
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {
|
||||
"vates/gallic": 20,
|
||||
"vates/xo-lib": 20,
|
||||
"vates/switchman": 20
|
||||
},
|
||||
"platform": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"platform-dev": [
|
||||
|
||||
]
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it
|
||||
* and/or modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Julien Fontanet <julien.fontanet@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0-standalone.html GPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
return array(
|
||||
|
||||
'xo' => array(
|
||||
'url' => 'tcp://localhost:1024',
|
||||
),
|
||||
|
||||
'templates' => array(
|
||||
|
||||
/* How long, in seconds, a compiled template should be
|
||||
* considered as up to date without checking its source file.
|
||||
*/
|
||||
'ttl' => 300, // 5 minutes.
|
||||
),
|
||||
);
|
@ -1,65 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it
|
||||
* and/or modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Julien Fontanet <julien.fontanet@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0-standalone.html GPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*
|
||||
* Local Variables:
|
||||
* mode: php
|
||||
* End:
|
||||
*/
|
||||
|
||||
/* Local settings
|
||||
*
|
||||
* This file contains all settings related to this current
|
||||
* installation of Xen Orchestra Web.
|
||||
*
|
||||
* You MUST define the following settings for which no default
|
||||
* values exists.
|
||||
*
|
||||
* But, you MAY override any settings which already exists in
|
||||
* “global.php”.
|
||||
*/
|
||||
return array(
|
||||
|
||||
'log' => array(
|
||||
|
||||
/* XO-Web can send you warnings and errors by email if you
|
||||
* provide an address.
|
||||
*/
|
||||
//'email' => 'your.email@provider.tld',
|
||||
|
||||
/* XO-Web can log all errors in a file if you provide one.
|
||||
*
|
||||
* Make sure this file is writable by the web server.
|
||||
*/
|
||||
//'file' => '#{root_dir}/log',
|
||||
),
|
||||
|
||||
'templates' => array(
|
||||
|
||||
/* In which directory should the compiled templates be saved.
|
||||
*
|
||||
* Default is PHP temporary directory.
|
||||
*/
|
||||
//'cache' => '#{root_dir}/cache',
|
||||
|
||||
),
|
||||
);
|
@ -1,87 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Julien Fontanet <julien.fontanet@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
/**
|
||||
* @todo Kill this class.
|
||||
*/
|
||||
final class Application extends Base
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function __construct(ServiceLocator $di)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->_sl = $di;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function getCurrentUser()
|
||||
{
|
||||
return isset($_SESSION['user']['name'])
|
||||
? $_SESSION['user']['name']
|
||||
: false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function logIn($name, $password)
|
||||
{
|
||||
$xo = $this->_sl->get('xo');
|
||||
|
||||
try
|
||||
{
|
||||
$xo->session->signInWithPassword($name, $password);
|
||||
}
|
||||
catch (XO_Exception $xo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$user = $xo->session->getUser();
|
||||
$user['token'] = $xo->session->createToken();
|
||||
$_SESSION['user'] = $user;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function logOut()
|
||||
{
|
||||
session_destroy();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var ServiceLocator
|
||||
*/
|
||||
private $_sl;
|
||||
}
|
51
lib/Base.php
51
lib/Base.php
@ -1,51 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Julien Fontanet <julien.fontanet@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ultimate base class.
|
||||
*/
|
||||
abstract class Base
|
||||
{
|
||||
function __destruct()
|
||||
{}
|
||||
|
||||
function __get($name)
|
||||
{
|
||||
trigger_error(
|
||||
'no such readable property '.get_class($this).'->'.$name,
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
function __set($name, $value)
|
||||
{
|
||||
trigger_error(
|
||||
'no such writable property '.get_class($this).'->'.$name,
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
protected function __construct()
|
||||
{}
|
||||
}
|
255
lib/Config.php
255
lib/Config.php
@ -1,255 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Julien Fontanet <julien.fontanet@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
final class Config extends Base implements
|
||||
ArrayAccess,
|
||||
Countable,
|
||||
IteratorAggregate
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function __construct(array $entries = null)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->_entries = isset($entries) ? $entries : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an entry.
|
||||
*
|
||||
* @param string $path
|
||||
* @param mixed $default Optional.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws Exception If there is no such entry and no default value as been
|
||||
* specified.
|
||||
*/
|
||||
function get($path, $default = 'throws an exception')
|
||||
{
|
||||
$entry = $this->_entries;
|
||||
|
||||
$parts = explode('.', $path);
|
||||
foreach ($parts as $part)
|
||||
{
|
||||
/*
|
||||
* Nothing found.
|
||||
*/
|
||||
if (!isset($entry[$part])
|
||||
&& !array_key_exists($part, $entry))
|
||||
{
|
||||
if (func_num_args() < 2)
|
||||
{
|
||||
throw new Exception('no such entry ('.$path.')');
|
||||
}
|
||||
|
||||
$entry = $default;
|
||||
break;
|
||||
}
|
||||
|
||||
$entry = $entry[$part];
|
||||
}
|
||||
|
||||
return $this->_resolve($entry);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function merge($entries)
|
||||
{
|
||||
if ($entries instanceof self)
|
||||
{
|
||||
$entries = $entries->_entries;
|
||||
}
|
||||
|
||||
self::_merge($this->_entries, $entries);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param string $path
|
||||
* @param array|string $value
|
||||
*/
|
||||
function set($path, $value)
|
||||
{
|
||||
$entry = &$this->_entries;
|
||||
|
||||
$parts = explode('.', $path);
|
||||
|
||||
$i = 0;
|
||||
$n = count($parts);
|
||||
while (
|
||||
($i < $n)
|
||||
&& (
|
||||
isset($entry[$part = $parts[$i]])
|
||||
|| (
|
||||
is_array($entry)
|
||||
&& array_key_exists($part, $entry)
|
||||
)
|
||||
)
|
||||
)
|
||||
{
|
||||
$entry = &$entry[$part];
|
||||
++$i;
|
||||
}
|
||||
|
||||
while ($i < $n)
|
||||
{
|
||||
if (!is_array($entry))
|
||||
{
|
||||
$entry = array();
|
||||
}
|
||||
|
||||
$entry = &$entry[$parts[$i]];
|
||||
++$i;
|
||||
}
|
||||
|
||||
$entry = $value;
|
||||
}
|
||||
|
||||
//--------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function offsetGet($offset)
|
||||
{
|
||||
return $this->get($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function offsetExists($offset)
|
||||
{
|
||||
return (isset($this->_entries[$offset])
|
||||
|| array_key_exists($offset, $this->_entries));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function offsetSet($offset, $value)
|
||||
{
|
||||
$this->set($offset, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function offsetUnset($index)
|
||||
{
|
||||
trigger_error(
|
||||
get_class($this).'['.var_export($index, true).'] is not deletable',
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
//--------------------------------------
|
||||
|
||||
/**
|
||||
* @return integer
|
||||
*/
|
||||
function count()
|
||||
{
|
||||
return count($this->_entries);
|
||||
}
|
||||
|
||||
//--------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function getIterator()
|
||||
{
|
||||
return \ArrayIterator($this->_entries);
|
||||
}
|
||||
|
||||
//--------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static private function _merge(array &$ar1, array $ar2)
|
||||
{
|
||||
foreach ($ar2 as $key => $val)
|
||||
{
|
||||
if (is_array($val)
|
||||
&& isset($ar1[$key])
|
||||
&& is_array($ar1[$key]))
|
||||
{
|
||||
self::_merge($ar1[$key], $val);
|
||||
}
|
||||
else
|
||||
{
|
||||
$ar1[$key] = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $_entries;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function _replaceCallback(array $match)
|
||||
{
|
||||
return $this->get($match[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function _resolve($entry)
|
||||
{
|
||||
if (is_string($entry))
|
||||
{
|
||||
return preg_replace_callback(
|
||||
'/#\{([-a-zA-Z0-9_.]+)\}/',
|
||||
array($this, '_replaceCallback'),
|
||||
$entry
|
||||
);
|
||||
}
|
||||
|
||||
if (is_array($entry))
|
||||
{
|
||||
foreach ($entry as &$item)
|
||||
{
|
||||
$item = $this->_resolve($item);
|
||||
}
|
||||
}
|
||||
|
||||
return $entry;
|
||||
}
|
||||
}
|
@ -1,184 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Julien Lambert <julien.fontanet@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
namespace Controller;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
final class Admin extends ControllerAbstract
|
||||
{
|
||||
function dispatch($action, array $route_parameters)
|
||||
{
|
||||
/* if ($action !== 'logIn') */
|
||||
/* { */
|
||||
/* return $this->_redirectTo('admin', 'logIn'); */
|
||||
/* } */
|
||||
|
||||
return parent::dispatch($action, $route_parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function indexAction()
|
||||
{
|
||||
return array(
|
||||
'admin' => true,
|
||||
'dashboard' => true,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function appsAction()
|
||||
{
|
||||
return array(
|
||||
'admin' => true,
|
||||
'apps' => true,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function eventsAction()
|
||||
{
|
||||
return array(
|
||||
'admin' => true,
|
||||
'events' => true,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function groupsAction()
|
||||
{
|
||||
return array(
|
||||
'admin' => true,
|
||||
'groups' => true,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function hostsAction()
|
||||
{
|
||||
return array(
|
||||
'admin' => true,
|
||||
'hosts' => true,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function policiesAction()
|
||||
{
|
||||
return array(
|
||||
'admin' => true,
|
||||
'policies' => true,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function usersAction()
|
||||
{
|
||||
$xo = $this->_sl->get('xo');
|
||||
|
||||
$referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : false;
|
||||
|
||||
if (isset($_GET['a']))
|
||||
{
|
||||
$action = $_GET['a'];
|
||||
try
|
||||
{
|
||||
if ($action === 'update')
|
||||
{
|
||||
$delete = isset($_POST['delete'])
|
||||
? $_POST['delete']
|
||||
: array();
|
||||
$old_perm = $_POST['old_perm'];
|
||||
$new_perm = $_POST['new_perm'];
|
||||
|
||||
foreach ($delete as $id => $_)
|
||||
{
|
||||
unset($new_perm[$id]);
|
||||
$xo->user->delete($id);
|
||||
}
|
||||
foreach ($new_perm as $id => $value)
|
||||
{
|
||||
if ($old_perm[$id] !== $value)
|
||||
{
|
||||
$xo->user->set($id, array(
|
||||
'permission' => $value,
|
||||
));
|
||||
}
|
||||
}
|
||||
return $this->_redirectToURL($referer ?: './');
|
||||
}
|
||||
if ($action === 'create')
|
||||
{
|
||||
$xo->user->create($_POST['name'], $_POST['password'], $_POST['permission']);
|
||||
return $this->_redirectToURL($referer ?: './');
|
||||
}
|
||||
}
|
||||
catch (XO_Exception $e)
|
||||
{
|
||||
$this->_sl->get('template.manager')
|
||||
->build('/_generic/error.templet')
|
||||
->render(array(
|
||||
'error' => ucfirst($action).' failed',
|
||||
'message' => $e->getMessage(),
|
||||
'referer' => $referer,
|
||||
));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$users = $xo->user->getAll();
|
||||
foreach ($users as &$user)
|
||||
{
|
||||
$user = (object) $user; // Template system only handles objects.
|
||||
}
|
||||
|
||||
return array(
|
||||
'admin' => true,
|
||||
'menu_admin_users' => true,
|
||||
'users' => $users,
|
||||
'permissions' => array(
|
||||
'None' => 'none',
|
||||
'Read' => 'read',
|
||||
'Write' => 'write',
|
||||
'Administration' => 'admin',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Julien Lambert <julien.fontanet@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
namespace Controller;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
abstract class ControllerAbstract
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function __construct(\ServiceLocator $sl)
|
||||
{
|
||||
$this->_sl = $sl;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __destruct()
|
||||
{}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function dispatch($action, array $route_parameters)
|
||||
{
|
||||
$response = $this->{$action.'Action'}($route_parameters);
|
||||
|
||||
if (is_array($response))
|
||||
{
|
||||
$name = strtolower(
|
||||
strtr(
|
||||
substr( // Remove “Controller\”.
|
||||
get_class($this),
|
||||
11
|
||||
),
|
||||
'\\',
|
||||
'_'
|
||||
)
|
||||
);
|
||||
|
||||
$this->_sl->get('template.manager')
|
||||
->build("/$name/$action.templet")
|
||||
->render($response);
|
||||
}
|
||||
elseif ($response instanceof \Response\Redirect)
|
||||
{
|
||||
header('Location: '.$response->url, $response->code);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------
|
||||
|
||||
/**
|
||||
* @var ServiceLocator
|
||||
*/
|
||||
protected $_sl;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function _redirectToURL($url)
|
||||
{
|
||||
return new \Response\Redirect($url);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function _redirectTo(
|
||||
$controller,
|
||||
$action,
|
||||
array $parameters = array()
|
||||
)
|
||||
{
|
||||
$parameters['controller'] = $controller;
|
||||
($action)
|
||||
or $parameters['action'] = $action;
|
||||
|
||||
// @todo Prefix base url.
|
||||
$url = $this->_sl->get('routes')->build('default', $parameters);
|
||||
return $this->_redirectToURL($url);
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Julien Lambert <julien.fontanet@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
namespace Controller;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
final class Home extends ControllerAbstract
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function indexAction()
|
||||
{
|
||||
$stats = $this->_sl->get('xo')->xo->getStats();
|
||||
// bytes to gigabytes then round
|
||||
$stats["memory"] = round($stats["memory"]/1024/1024/1024,2);
|
||||
return array(
|
||||
'index' => true,
|
||||
'connected' => (0 !== $stats['hosts']),
|
||||
'stats' => (object) $stats,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function sessionAction()
|
||||
{
|
||||
$app = $this->_sl->get('application');
|
||||
$tm = $this->_sl->get('template.manager');
|
||||
|
||||
$referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : false;
|
||||
|
||||
if (!$referer)
|
||||
{
|
||||
$tm->build('/_generic/error.templet')->render();
|
||||
return;
|
||||
}
|
||||
|
||||
// @todo Does not work anymore.
|
||||
$self =
|
||||
(isset($_SERVER['https']) ? 'https' : 'http').
|
||||
'://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
|
||||
if ($referer === $self)
|
||||
{
|
||||
$referer = false;
|
||||
}
|
||||
|
||||
if (isset($_POST['name'], $_POST['password']))
|
||||
{
|
||||
if (!$app->logIn($_POST['name'], $_POST['password']))
|
||||
{
|
||||
$tm->build('/_generic/error.templet')->render(array(
|
||||
'error' => 'Log in failed',
|
||||
// @todo 'message' => '',
|
||||
'referer' => $referer,
|
||||
));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$app->logOut();
|
||||
}
|
||||
|
||||
return $this->_redirectToURL($referer ?: './');
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Julien Lambert <julien.fontanet@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
namespace Controller;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
final class Logs extends ControllerAbstract
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function indexAction()
|
||||
{
|
||||
return array(
|
||||
'storage' => true,
|
||||
);
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Julien Lambert <julien.fontanet@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
namespace Controller;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
final class Network extends ControllerAbstract
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function indexAction()
|
||||
{
|
||||
$pools = $this->_sl->get('xo')->network->getAll();
|
||||
|
||||
// If there is the “json” parameter, just print the JSON.
|
||||
if (isset($_GET['json']))
|
||||
{
|
||||
echo json_encode($pools);
|
||||
return;
|
||||
}
|
||||
|
||||
return array(
|
||||
'pools' => $pools,
|
||||
);
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Julien Lambert <julien.fontanet@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
namespace Controller;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
final class Pools extends ControllerAbstract
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function indexAction()
|
||||
{
|
||||
return array(
|
||||
'pool' => true,
|
||||
);
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Julien Lambert <julien.fontanet@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
namespace Controller;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
final class Servers extends ControllerAbstract
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function indexAction()
|
||||
{
|
||||
$pools = $this->_sl->get('xo')->host->getAll();
|
||||
|
||||
// If there is the “json” parameter, just print the JSON.
|
||||
if (isset($_GET['json']))
|
||||
{
|
||||
echo json_encode($pools);
|
||||
return;
|
||||
}
|
||||
|
||||
return array(
|
||||
'pools' => $pools,
|
||||
);
|
||||
}
|
||||
|
||||
function showAction(array $route_params)
|
||||
{
|
||||
$host = $this->_sl->get('xo')->host->get($route_params['uuid']);
|
||||
|
||||
// If there is the “json” parameter, just print the JSON.
|
||||
if (isset($_GET['json']))
|
||||
{
|
||||
echo json_encode($host);
|
||||
return;
|
||||
}
|
||||
|
||||
return array(
|
||||
'host' => $host,
|
||||
);
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Julien Lambert <julien.fontanet@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
namespace Controller;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
final class Storage extends ControllerAbstract
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function indexAction()
|
||||
{
|
||||
$pools = $this->_sl->get('xo')->storage->getAll();
|
||||
|
||||
// If there is the “json” parameter, just print the JSON.
|
||||
if (isset($_GET['json']))
|
||||
{
|
||||
echo json_encode($pools);
|
||||
return;
|
||||
}
|
||||
|
||||
return array(
|
||||
'pools' => $pools,
|
||||
);
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Julien Lambert <julien.fontanet@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
namespace Controller;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
final class Templates extends ControllerAbstract
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function indexAction()
|
||||
{
|
||||
$tpls = $this->_sl->get('xo')->template->getAll();
|
||||
|
||||
// Groups VMs by pools.
|
||||
$by_pools = array();
|
||||
foreach ($tpls as $tpl)
|
||||
{
|
||||
// Backbone requires primary key to be called “id”.
|
||||
$tpl['id'] = $tpl['uuid']; unset($tpl['uuid']);
|
||||
|
||||
// Makes sure the null pool is recognized and sorted at the end.
|
||||
$pool_uuid = $tpl['pool_uuid'] ?: 'z';
|
||||
|
||||
$by_pools[$pool_uuid][] = $tpl;
|
||||
}
|
||||
|
||||
$pools = array();
|
||||
foreach ($by_pools as $pool_uuid => $tpls)
|
||||
{
|
||||
$pools[] = array(
|
||||
'id' => $pool_uuid,
|
||||
'name' => $tpls[0]['pool_name'],
|
||||
'templates' => $tpls,
|
||||
);
|
||||
}
|
||||
|
||||
// If there is the “json” parameter, just print the JSON.
|
||||
if (isset($_GET['json']))
|
||||
{
|
||||
echo json_encode($pools);
|
||||
return;
|
||||
}
|
||||
|
||||
return array(
|
||||
'pools' => $pools,
|
||||
);
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Julien Lambert <julien.fontanet@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
namespace Controller;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
final class VMs extends ControllerAbstract
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function indexAction()
|
||||
{
|
||||
$vms = $this->_sl->get('xo')->vm->getAll();
|
||||
|
||||
// Groups VMs by hosts.
|
||||
$by_hosts = array();
|
||||
foreach ($vms as $vm)
|
||||
{
|
||||
// Backbone requires primary key to be called “id”.
|
||||
$vm['id'] = $vm['uuid']; unset($vm['uuid']);
|
||||
|
||||
// Makes sure the null host is recognized and sorted at the end.
|
||||
$host_uuid = $vm['host_uuid'] ?: 'z';
|
||||
|
||||
$by_hosts[$host_uuid][] = $vm;
|
||||
}
|
||||
|
||||
$hosts = array();
|
||||
foreach ($by_hosts as $host_uuid => $vms)
|
||||
{
|
||||
$hosts[] = array(
|
||||
'id' => $host_uuid,
|
||||
'name' => $vms[0]['host_name'],
|
||||
'vms' => $vms,
|
||||
);
|
||||
}
|
||||
|
||||
// If there is the “json” parameter, just print the JSON.
|
||||
if (isset($_GET['json']))
|
||||
{
|
||||
echo json_encode($hosts);
|
||||
return;
|
||||
}
|
||||
|
||||
return array(
|
||||
'hosts' => $hosts,
|
||||
);
|
||||
}
|
||||
|
||||
function showAction(array $route_params)
|
||||
{
|
||||
$vm = $this->_sl->get('xo')->vm->get($route_params['uuid']);
|
||||
|
||||
// Backbone requires primary key to be called “id”.
|
||||
$vm['id'] = $vm['uuid']; unset($vm['uuid']);
|
||||
|
||||
// If there is the “json” parameter, just print the JSON.
|
||||
if (isset($_GET['json']))
|
||||
{
|
||||
echo json_encode($vm);
|
||||
return;
|
||||
}
|
||||
|
||||
return array(
|
||||
'vm' => $vm,
|
||||
);
|
||||
}
|
||||
}
|
@ -1,110 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Julien Fontanet <julien.fontanet@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
use \Monolog\Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
final class ErrorLogger extends Base
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function __construct(Logger $logger)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->_logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles fatal errors on shutdown.
|
||||
*/
|
||||
function handleShutdown()
|
||||
{
|
||||
$e = error_get_Last();
|
||||
if ((($e['type'] === E_ERROR) || ($e['type'] === E_USER_ERROR))
|
||||
&& ($e !== $this->_last))
|
||||
{
|
||||
$this->log($e['type'], $e['message'], $e['file'], $e['line']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function log($no, $str, $file, $line)
|
||||
{
|
||||
static $map = array(
|
||||
E_NOTICE => Logger::NOTICE,
|
||||
E_USER_NOTICE => Logger::NOTICE,
|
||||
E_WARNING => Logger::WARNING,
|
||||
E_CORE_WARNING => Logger::WARNING,
|
||||
E_USER_WARNING => Logger::WARNING,
|
||||
E_ERROR => Logger::ERROR,
|
||||
E_USER_ERROR => Logger::ERROR,
|
||||
E_CORE_ERROR => Logger::ERROR,
|
||||
E_RECOVERABLE_ERROR => Logger::ERROR,
|
||||
E_STRICT => Logger::DEBUG,
|
||||
);
|
||||
|
||||
// Used to prevents the last error from being logged twice.
|
||||
$this->_last = array(
|
||||
'type' => $no,
|
||||
'message' => $str,
|
||||
'file' => $file,
|
||||
'line' => $line
|
||||
);
|
||||
|
||||
$priority = isset($map[$no])
|
||||
? $map[$no]
|
||||
: Logger::WARNING
|
||||
;
|
||||
|
||||
// Appends the location if necessary.
|
||||
if (!preg_match('/(?:at|in) [^ ]+:[0-9]+$/', $str))
|
||||
{
|
||||
$str .= " in $file:$line";
|
||||
}
|
||||
|
||||
$this->_logger->addRecord($priority, $str, array(
|
||||
'no' => $no,
|
||||
'file' => $file,
|
||||
'line' => $line,
|
||||
));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private $_last;
|
||||
|
||||
/**
|
||||
* @var Logger
|
||||
*/
|
||||
private $_logger;
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Julien Lambert <julien.fontanet@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
abstract class Response
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function __construct()
|
||||
{}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function __destruct()
|
||||
{}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Julien Lambert <julien.fontanet@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
namespace Response;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
final class Redirect extends \Response
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public $url;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public $code = 302;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function __construct($url)
|
||||
{
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function withCode($code)
|
||||
{
|
||||
$this->_code = $code;
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -1,249 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Julien Fontanet <julien.fontanet@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
/**
|
||||
* Service locator.
|
||||
*/
|
||||
final class ServiceLocator extends Base
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
function get($id, $default = 'throws an exception')
|
||||
{
|
||||
if (isset($this->_entries[$id])
|
||||
|| array_key_exists($id, $this->_entries))
|
||||
{
|
||||
return $this->_entries[$id];
|
||||
}
|
||||
|
||||
$tmp = str_replace(array('_', '.'), array('', '_'), $id);
|
||||
|
||||
if (method_exists($this, '_get_'.$tmp))
|
||||
{
|
||||
return $this->{'_get_'.$tmp}();
|
||||
}
|
||||
|
||||
if (method_exists($this, '_init_'.$tmp))
|
||||
{
|
||||
$value = $this->{'_init_'.$tmp}();
|
||||
$this->set($id, $value);
|
||||
return $value;
|
||||
}
|
||||
|
||||
// Last chance: maybe its a class name.
|
||||
if (class_exists($id))
|
||||
{
|
||||
return new $id;
|
||||
}
|
||||
|
||||
// Nothing found.
|
||||
if (func_num_args() < 2)
|
||||
{
|
||||
throw new Exception('no such entry ('.$path.')');
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
function set($id, $value)
|
||||
{
|
||||
$this->_entries[$id] = $value;
|
||||
}
|
||||
|
||||
private $_entries = array();
|
||||
|
||||
////////////////////////////////////////œ
|
||||
|
||||
private function _init_application()
|
||||
{
|
||||
return new Application($this);
|
||||
}
|
||||
|
||||
private function _init_controller_admin()
|
||||
{
|
||||
return new Controller\Admin($this);
|
||||
}
|
||||
|
||||
private function _init_controller_home()
|
||||
{
|
||||
return new Controller\Home($this);
|
||||
}
|
||||
|
||||
private function _init_controller_pools()
|
||||
{
|
||||
return new Controller\Pools($this);
|
||||
}
|
||||
|
||||
private function _init_controller_servers()
|
||||
{
|
||||
return new Controller\Servers($this);
|
||||
}
|
||||
|
||||
private function _init_controller_templates()
|
||||
{
|
||||
return new Controller\Templates($this);
|
||||
}
|
||||
|
||||
private function _init_controller_storage()
|
||||
{
|
||||
return new Controller\Storage($this);
|
||||
}
|
||||
|
||||
private function _init_controller_logs()
|
||||
{
|
||||
return new Controller\Logs($this);
|
||||
}
|
||||
|
||||
private function _init_controller_network()
|
||||
{
|
||||
return new Controller\Network($this);
|
||||
}
|
||||
|
||||
private function _init_controller_vms()
|
||||
{
|
||||
return new Controller\VMs($this);
|
||||
}
|
||||
|
||||
private function _init_errorLogger()
|
||||
{
|
||||
return new ErrorLogger($this->get('logger'));
|
||||
}
|
||||
|
||||
private function _init_logger()
|
||||
{
|
||||
$logger = new \Monolog\Logger('main');
|
||||
|
||||
$config = $this->get('config');
|
||||
if ($email = $config->get('log.email', false))
|
||||
{
|
||||
$logger->pushHandler(
|
||||
new \Monolog\Handler\FingersCrossedHandler(
|
||||
new \Monolog\Handler\NativeMailerHandler(
|
||||
$email,
|
||||
'[XO Web]',
|
||||
'no-reply@vates.fr',
|
||||
\Monolog\Logger::DEBUG
|
||||
),
|
||||
\Monolog\Logger::WARNING
|
||||
)
|
||||
);
|
||||
}
|
||||
if ($file = $config->get('log.file', false))
|
||||
{
|
||||
$logger->pushHandler(
|
||||
new \Monolog\Handler\StreamHandler($file)
|
||||
);
|
||||
}
|
||||
|
||||
return $logger;
|
||||
}
|
||||
|
||||
private function _init_routes()
|
||||
{
|
||||
$base = $this->get('config')->get('base_path');
|
||||
|
||||
return new \Switchman\Collection(
|
||||
/* builders */ array(
|
||||
'default' => array(
|
||||
'class' => '\Switchman\Builder\Simple',
|
||||
'options' => array(
|
||||
'pattern' => $base.'/:controller/:action',
|
||||
'defaults' => array(
|
||||
'action' => 'index',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
/* matchers */ array(
|
||||
'default' => array(
|
||||
'class' => '\Switchman\Matcher\Regex',
|
||||
'options' => array(
|
||||
'patterns' => array(
|
||||
'path' => ',^/(?:(?<controller>[a-z]+)(?:/(?<action>[a-z]+))?/?)?$,i',
|
||||
),
|
||||
'defaults' => array(
|
||||
'controller' => 'home',
|
||||
'action' => 'index'
|
||||
),
|
||||
),
|
||||
),
|
||||
'show-item' => array(
|
||||
'class' => '\Switchman\Matcher\Regex',
|
||||
'options' => array(
|
||||
'patterns' => array(
|
||||
'path' => ',^/(?:(?<controller>[a-z]+))/(?<uuid>[a-z0-9-]+)$,i',
|
||||
),
|
||||
'defaults' => array(
|
||||
'action' => 'show'
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private function _init_template_manager()
|
||||
{
|
||||
$config = $this->get('config');
|
||||
|
||||
$tm = new Gallic_Template_Manager(
|
||||
__DIR__.'/../views',
|
||||
$config['templates.ttl'],
|
||||
$config->get('templates.cache', null)
|
||||
);
|
||||
|
||||
$tm->defaultFilters += array(
|
||||
'count' => 'count',
|
||||
'json' => 'json_encode',
|
||||
);
|
||||
|
||||
$tu = new TemplateUtils($this);
|
||||
$tm->defaultFunctions += array(
|
||||
'generateSelectOptions' => array($tu, 'generateSelectOptions'),
|
||||
'url' => array($tu, 'url'),
|
||||
);
|
||||
|
||||
$tm->defaultVariables += array(
|
||||
'base_path' => $config['base_path'],
|
||||
'user' => $this->get('application')->getCurrentUser(),
|
||||
);
|
||||
|
||||
return $tm;
|
||||
}
|
||||
|
||||
private function _init_xo()
|
||||
{
|
||||
$xo = new XO($this->get('config')->get('xo.url'));
|
||||
|
||||
if (isset($_SESSION['user']['token']))
|
||||
{
|
||||
$xo->session->signInWithToken($_SESSION['user']['token']);
|
||||
}
|
||||
|
||||
return $xo;
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Julien Fontanet <julien.fontanet@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
final class TemplateUtils
|
||||
{
|
||||
function __construct(ServiceLocator $sl)
|
||||
{
|
||||
$this->_sl = $sl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var ServiceLocator
|
||||
*/
|
||||
private $_sl;
|
||||
|
||||
//--------------------------------------
|
||||
|
||||
function generateSelectOptions(
|
||||
Gallic_Template $tpl,
|
||||
array $parameters
|
||||
)
|
||||
{
|
||||
$options = $parameters['options'];
|
||||
$selected = isset($parameters['selected'])
|
||||
? $parameters['selected']
|
||||
: null;
|
||||
|
||||
$html = '';
|
||||
foreach ($options as $name => $value)
|
||||
{
|
||||
$html .=
|
||||
"<option value=\"$value\"".
|
||||
($value === $selected ? ' selected="selected"' : '').
|
||||
">$name</option>";
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
function url(Gallic_Template $tpl, array $parameters)
|
||||
{
|
||||
if (!isset($parameters[0]))
|
||||
{
|
||||
$parameters[0] = 'default';
|
||||
|
||||
isset($parameters['controller'])
|
||||
or $parameters['controller'] = $this->_sl->get('current_controller');
|
||||
}
|
||||
|
||||
return $this->_sl->get('routes')->build($parameters[0], $parameters);
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_FILENAME} -s [OR]
|
||||
RewriteCond %{REQUEST_FILENAME} -l [OR]
|
||||
RewriteCond %{REQUEST_FILENAME} -d
|
||||
RewriteRule ^.*$ - [NC,L]
|
||||
RewriteRule ^.*$ index.php [NC,L]
|
23
public/.jshintrc
Normal file
23
public/.jshintrc
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"bitwise": true,
|
||||
"browser": true,
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"es5": true,
|
||||
"immed": false,
|
||||
"latedef": true,
|
||||
"maxcomplexity": 10,
|
||||
"maxdepth": 5,
|
||||
"maxlen": 80,
|
||||
"maxparams": 4,
|
||||
"maxstatements": 20,
|
||||
"newcap": true,
|
||||
"noempty": true,
|
||||
"nonew": true,
|
||||
"quotmark": true,
|
||||
"smarttabs": true,
|
||||
"strict": false,
|
||||
"trailing": true,
|
||||
"undef": true,
|
||||
"unused": true
|
||||
}
|
309
public/index.html
Normal file
309
public/index.html
Normal file
@ -0,0 +1,309 @@
|
||||
<!-- HTML 5 Doctype -->
|
||||
<!DOCTYPE html>
|
||||
|
||||
<!-- The “no-js” class will be automatically removed if JavaScript is
|
||||
- available.
|
||||
-->
|
||||
<html lang="en" dir="ltr" class="no-js">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<!--
|
||||
- This file is a part of Xen Orchestra Web.
|
||||
-
|
||||
- Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
- modify it under the terms of the GNU Affero General Public License
|
||||
- as published by the Free Software Foundation, either version 3 of
|
||||
- the License, or (at your option) any later version.
|
||||
-
|
||||
- Xen Orchestra Web is distributed in the hope that it will be
|
||||
- useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with Xen Orchestra Web. If not, see
|
||||
- <http://www.gnu.org/licenses/>.
|
||||
-
|
||||
- @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
- @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
-
|
||||
- @package Xen Orchestra Web
|
||||
-->
|
||||
|
||||
<!-- Makes sure IE is using the last engine available. -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
|
||||
<!-- Replaces the “no-js” class by the “js” class if JavaScript
|
||||
- is available.
|
||||
-->
|
||||
<script>!function(d){d.className=d.className.replace(/\bno-js\b/,'js')}(document.documentElement)</script>
|
||||
|
||||
<!-- HTML5 shim, for IE6-8 support of HTML5 elements. -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<!-- (To confirm.) For smartphones and tablets: sets the page
|
||||
- width to the device width and prevents the page from being
|
||||
- zoomed in when going to landscape mode.
|
||||
-->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<title>Xen Orchestra</title>
|
||||
|
||||
<meta name="description" content="Web Interface for XCP" />
|
||||
<meta name="author" content="Olivier Lambert and Julien Fontanet" />
|
||||
|
||||
<!-- We use Bootstrap CSS. -->
|
||||
<link rel="stylesheet" href="./css/bootstrap.css" />
|
||||
|
||||
<!-- This font is used for icons. -->
|
||||
<link rel="stylesheet" href="./css/font-awesome.css" />
|
||||
|
||||
<!-- Our stylesheet and scripts. -->
|
||||
<link rel="stylesheet" href="./css/style.css" />
|
||||
<link rel="icon" type="image/png" href="./img/favicon.png" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a id="tour_home" class="brand" href="#">
|
||||
<img src="./img/bannerb.png" alt="Xen Orchestra" />
|
||||
</a>
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li class="divider-vertical"></li>
|
||||
<li id="tour_host">
|
||||
<a href="#hosts"><i class="icon-cloud"></i> Host</a>
|
||||
</li>
|
||||
<li id="tour_vm">
|
||||
<a href="#vms"><i class="icon-desktop"></i> Vm</a>
|
||||
</li>
|
||||
<li id="tour_misc" class="dropdown">
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
<i class="icon-cog"></i> Misc <b class="icon-caret-down"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#templates"><i class="icon-file-alt"></i> Template</a></li>
|
||||
<li><a href="#storages"><i class="icon-hdd"></i> Storage</a></li>
|
||||
<li><a href="#networks"><i class="icon-sitemap"></i> Network</a></li>
|
||||
<li class="disabled"><a href="#"><i class="icon-comment"></i> Logs</a></li>
|
||||
<li class="divider"></li>
|
||||
<li class="disabled"><a href="#"><i class="icon-asterisk"></i> Other</a></li>
|
||||
</ul>
|
||||
</ul>
|
||||
<ul class="nav pull-right">
|
||||
<li class="divider-vertical"></li>
|
||||
<li id="tour_setting">
|
||||
<a title="Settings" href="#admin"><i class="icon-wrench"></i></a>
|
||||
</li>
|
||||
<li class="disabled">
|
||||
<a id="msg" href="#"><i class="icon-bell"></i></a>
|
||||
</li>
|
||||
|
||||
<!--
|
||||
- Session.
|
||||
-->
|
||||
<!-- {if $user}
|
||||
<li>
|
||||
<a title="My profile" href="#"><i class="icon-user"></i> {$user}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a title="Log-Out" href="{url controller="home" action="session"}"> <i class="icon-signout"></i></a>
|
||||
</li>
|
||||
{else} -->
|
||||
<li id="tour_login" class="dropdown">
|
||||
<a class="dropdown-toggle" href="#" data-toggle="dropdown">
|
||||
<i class="icon-signin"></i> Log In <i class="icon-caret-down"></i>
|
||||
</a>
|
||||
<div class="dropdown-menu" style="padding: 15px; padding-bottom: 0px;">
|
||||
<form action="#/home/session" method="post">
|
||||
<div class="input-prepend">
|
||||
<span class="add-on"><i class="icon-user"></i></span>
|
||||
<input class="span2" type="text" placeholder="User" name="name" required />
|
||||
</div>
|
||||
<div class="input-prepend">
|
||||
<span class="add-on"><i class="icon-key"></i></span>
|
||||
<input class="span2" type="password" placeholder="Password" name="password" required /><br /><br />
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="icon-signin icon-small"></i> Log In
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</li>
|
||||
<!-- {/if} -->
|
||||
|
||||
</ul>
|
||||
|
||||
<form id="tour_search" class="input-prepend navbar-search pull-right navbar-search" action="post">
|
||||
<span class="add-on"><i class="icon-search"></i></span>
|
||||
<input type="text" class="span2 inputIcon" placeholder="Search" disabled/>
|
||||
</form>
|
||||
</div><!-- /.nav-collapse -->
|
||||
</div><!-- /.container -->
|
||||
</div><!-- /.navbar-inner -->
|
||||
</div><!-- /.navbar -->
|
||||
|
||||
<!--==============================================================
|
||||
= Regions.
|
||||
==============================================================-->
|
||||
|
||||
<!-- Main content region -->
|
||||
<div id="reg-main"></div>
|
||||
|
||||
<!--==============================================================
|
||||
= Templates.
|
||||
==============================================================-->
|
||||
|
||||
<!-- Home page with the statistics. -->
|
||||
<script type="text/template" id="tpl-stats">
|
||||
<div class="row-fluid">
|
||||
<div class="span10 offset1 hero-unit">
|
||||
<h2 class="center">XO Dashboard</h2>
|
||||
|
||||
<div class="row-fluid offset1">
|
||||
<div class="row-fluid span3 center">
|
||||
<h2>
|
||||
<%= hosts %>x
|
||||
<a href="#hosts"><i class="icon-cloud icon-2x"></i></a>
|
||||
</h2>
|
||||
<p>hosts running</p>
|
||||
</div>
|
||||
<div class="row-fluid span3 center">
|
||||
<h2>
|
||||
<%= running_vms %>x
|
||||
<a href="#vms"><i class="icon-desktop icon-2x"></i></a>
|
||||
</h2>
|
||||
<p>of <%= vms %> VMs running</p>
|
||||
</div>
|
||||
<div class="row-fluid span3 center">
|
||||
<h2>
|
||||
<%= srs %>x
|
||||
<a href="#storages"><i class="icon-hdd icon-2x"></i></a>
|
||||
</h2>
|
||||
<p>shared repositories</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid offset1">
|
||||
<div class="row-fluid span3 center">
|
||||
<h2>
|
||||
<%= vcpus %>x
|
||||
<i class="icon-dashboard icon-2x"></i>
|
||||
</h2>
|
||||
<p>vCPUs used</p>
|
||||
</div>
|
||||
<div class="row-fluid span3 center">
|
||||
<h2>
|
||||
<%= formatSize(memory) %>
|
||||
<i class="icon-tasks icon-2x"></i>
|
||||
</h2>
|
||||
<p>of RAM allocated</p>
|
||||
</div>
|
||||
<div class="row-fluid span3 center">
|
||||
<h2>
|
||||
<%= vifs %>x
|
||||
<i class="icon-sitemap icon-2x"></i>
|
||||
</h2>
|
||||
<p>virtual interfaces up</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span3 well offset1">
|
||||
<h2 class="center">Need help?</h2>
|
||||
<p>If you don't know how to start, please read the README first. Then, if you have further questions, please read the FAQ on the project website.
|
||||
</p><br/>
|
||||
<p class="center"><a class="btn btn-info btn-large start" href="#" ><i class="icon-info-sign"></i> Start tour</a></p>
|
||||
</div>
|
||||
<div class="span4 well">
|
||||
<h2 class="center">About us</h2>
|
||||
<p>We are the team behind XO, we are Vates! We create Open Source products and we offer commercial support for Xen and Xen Orchestra. This project is Open Source (AGPL), everyone is welcome aboard!</p><br/>
|
||||
<p class="center"><a class="btn btn-large" href="http://vates.fr"><i class="icon-circle-arrow-right"></i> Go on our website!</a></p>
|
||||
</div>
|
||||
<div class="span3 well">
|
||||
<h2 class="center">Get involved!</h2>
|
||||
<p>You want a specific feature in XO? Report a bug? Go to our project website, read the FAQ and get involved in the project!</p><br/>
|
||||
<p class="center"><a class="btn btn-success btn-large" href="http://xen-orchestra.com"><i class="icon-beaker"></i> Project page</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<!-- Hosts list. -->
|
||||
<script type="text/template" id="tpl-hosts-list">
|
||||
<h3 class="center"><%= link(name, ['pools', id]) %></h3>
|
||||
|
||||
<table class="table table-bordered table-hover table-striped">
|
||||
<thead>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<th>Memory</th>
|
||||
<th>Addresses</th>
|
||||
<th>Uptime</th>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</script>
|
||||
<script type="text/template" id="tpl-hosts-list-item">
|
||||
<td><%= link(name, ['servers', 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>
|
||||
|
||||
<!-- VMs list. -->
|
||||
<script type="text/template" id="tpl-vms-list">
|
||||
<h3 class="center"><%= name %></h3>
|
||||
|
||||
<table class="table table-bordered table-hover table-striped">
|
||||
<thead>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<th>CPU Usage</th>
|
||||
<th>Memory</th>
|
||||
<th>Disk</th>
|
||||
<th>Network</th>
|
||||
<th>Address</th>
|
||||
<th>Uptime</th>
|
||||
<th>State</th>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</script>
|
||||
<script type="text/template" id="tpl-vms-list-item">
|
||||
<% var usage = 100 - Math.round(100*memory.free/memory.total) %>
|
||||
|
||||
<td><%= link(name, ['vms', id]) %></td>
|
||||
<td><%= description %></td>
|
||||
<td><%= progressBar(10, {'label': '10%'}) %></td><!-- @todo -->
|
||||
<td><%= used_memory ? progressBar(100*used_memory/total_memory) : formatSize(total_memory) %></td>
|
||||
<td><%= VBDs %></td>
|
||||
<td><%= VIFs %></td>
|
||||
<td><%= _.values(networks).join(', ') %></td>
|
||||
<td><%= start_time ? formatDuration_fromNow(start_time) : 'N/A' %></td>
|
||||
<td><%= powerState() %></td>
|
||||
</script>
|
||||
|
||||
<!-- JS Placed at the end of the document so the pages load faster -->
|
||||
<script src="http://underscorejs.org/underscore.js"></script>
|
||||
<script src="./js/jquery.js"></script>
|
||||
<script src="./js/backbone.js"></script>
|
||||
<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.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,93 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bootstraps the application and returns the service locator.
|
||||
*
|
||||
* @return ServiceLocator
|
||||
*/
|
||||
function _bootstrap()
|
||||
{
|
||||
// First of all, starts the session.
|
||||
session_start();
|
||||
|
||||
// Class autoloading is done by composer.
|
||||
require(__DIR__.'/../vendor/autoload.php');
|
||||
|
||||
// Reads configuration.
|
||||
$config = new Config;
|
||||
foreach (array('global', 'local') as $file)
|
||||
{
|
||||
$file = __DIR__.'/../config/'.$file.'.php';
|
||||
if (is_file($file))
|
||||
{
|
||||
$config->merge(require($file));
|
||||
}
|
||||
}
|
||||
|
||||
// Injects some variables.
|
||||
$config['root_dir'] = __DIR__.'/..';
|
||||
|
||||
// Creates the service locator
|
||||
$locator = new ServiceLocator;
|
||||
$locator->set('config', $config);
|
||||
|
||||
// Loggs all errors.
|
||||
$error_logger = $locator->get('error_logger');
|
||||
set_error_handler(array($error_logger, 'log'));
|
||||
register_shutdown_function(array($error_logger, 'handleShutdown'));
|
||||
|
||||
return $locator;
|
||||
}
|
||||
|
||||
// Bootstraps the application and gets the locator.
|
||||
$locator = _bootstrap();
|
||||
|
||||
// Creates the current context.
|
||||
$context = \Switchman\Context\HTTP::createFromGlobals(true);
|
||||
$locator->get('config')->set('base_path', $context['base_path']);
|
||||
|
||||
// Gets the available routes.
|
||||
$routes = $locator->get('routes');
|
||||
|
||||
// Matches the routes to obtain current parameters.
|
||||
$parameters = $routes->match($context);
|
||||
|
||||
// Basic error message if no route found.
|
||||
if (!$parameters
|
||||
|| !($controller = $locator->get('controller.'.$parameters['controller'], false)))
|
||||
{
|
||||
header('HTTP/1.1 404 Not Found');
|
||||
|
||||
trigger_error(
|
||||
'no route found for: '.$context['path'],
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
// @todo Not sure it is the right place to put the current route.
|
||||
$locator->set('current_controller', $parameters['controller']);
|
||||
|
||||
// Dispatches the current action.
|
||||
$controller->dispatch($parameters['action'], $parameters);
|
@ -1,123 +0,0 @@
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
!function ()
|
||||
{
|
||||
"use strict";
|
||||
|
||||
//--------------------------------------
|
||||
// Models & collections.
|
||||
//--------------------------------------
|
||||
|
||||
var PIF = Backbone.Model.extend({});
|
||||
var PIFs = Backbone.Collection.extend({
|
||||
'model': PIF,
|
||||
});
|
||||
|
||||
function updatePIFs()
|
||||
{
|
||||
var raw = this.get('PIFs');
|
||||
var col = this.previous('PIFs');
|
||||
col.update(raw);
|
||||
this.set('PIFs', col, {'silent': true});
|
||||
}
|
||||
var Pool = Backbone.Model.extend({
|
||||
'initialize': function () {
|
||||
var PIFs_ = this.get('PIFs');
|
||||
if (PIFs_ instanceof Array)
|
||||
{
|
||||
this.set('PIFs', new PIFs(PIFs_), {'silent': true});
|
||||
}
|
||||
this.on('change:PIFs', updatePIFs, this);
|
||||
},
|
||||
});
|
||||
var Pools = Backbone.Collection.extend({
|
||||
'model': Pool,
|
||||
});
|
||||
|
||||
//--------------------------------------
|
||||
// Views.
|
||||
//--------------------------------------
|
||||
|
||||
var PIFView = Backbone.Marionette.ItemView.extend({
|
||||
'template': '#tpl-network',
|
||||
'tagName': 'tr',
|
||||
|
||||
'modelEvents': {
|
||||
'change': 'render',
|
||||
},
|
||||
});
|
||||
|
||||
var PoolView = Backbone.Marionette.CompositeView.extend({
|
||||
'template': '#tpl-pool',
|
||||
|
||||
'model': Pool,
|
||||
|
||||
'itemView': PIFView,
|
||||
'itemViewContainer': 'tbody',
|
||||
|
||||
'initialize': function () {
|
||||
// Grab the collection of PIFs from the pool model.
|
||||
this.collection = this.model.get('PIFs');
|
||||
},
|
||||
});
|
||||
|
||||
var PoolsView = Backbone.Marionette.CollectionView.extend({
|
||||
'itemView': PoolView,
|
||||
});
|
||||
|
||||
//--------------------------------------
|
||||
// Application.
|
||||
//--------------------------------------
|
||||
|
||||
var app = new Backbone.Marionette.Application();
|
||||
|
||||
app.addRegions({
|
||||
'main': '#region-main',
|
||||
});
|
||||
|
||||
app.addInitializer(function (pools) {
|
||||
app.main.show(
|
||||
new PoolsView({'collection': pools})
|
||||
);
|
||||
});
|
||||
|
||||
//--------------------------------------
|
||||
// Execution.
|
||||
//--------------------------------------
|
||||
|
||||
$(function () {
|
||||
var pools = new Pools(window.pools);
|
||||
app.start(pools);
|
||||
|
||||
function refresh()
|
||||
{
|
||||
$.ajax('?json').done(function (data, status, jqXHR) {
|
||||
pools.update($.parseJSON(data));
|
||||
});
|
||||
|
||||
window.setTimeout(refresh, 5000);
|
||||
}
|
||||
window.setTimeout(refresh, 5000);
|
||||
});
|
||||
}();
|
@ -1,123 +0,0 @@
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
!function ()
|
||||
{
|
||||
"use strict";
|
||||
|
||||
//--------------------------------------
|
||||
// Models & collections.
|
||||
//--------------------------------------
|
||||
|
||||
var Host = Backbone.Model.extend({});
|
||||
var Hosts = Backbone.Collection.extend({
|
||||
'model': Host,
|
||||
});
|
||||
|
||||
function updateHosts()
|
||||
{
|
||||
var raw = this.get('hosts');
|
||||
var col = this.previous('hosts');
|
||||
col.update(raw);
|
||||
this.set('hosts', col, {'silent': true});
|
||||
}
|
||||
var Pool = Backbone.Model.extend({
|
||||
'initialize': function () {
|
||||
var hosts = this.get('hosts');
|
||||
if (hosts instanceof Array)
|
||||
{
|
||||
this.set('hosts', new Hosts(hosts), {'silent': true});
|
||||
}
|
||||
this.on('change:hosts', updateHosts, this);
|
||||
},
|
||||
});
|
||||
var Pools = Backbone.Collection.extend({
|
||||
'model': Pool,
|
||||
});
|
||||
|
||||
//--------------------------------------
|
||||
// Views.
|
||||
//--------------------------------------
|
||||
|
||||
var HostView = Backbone.Marionette.ItemView.extend({
|
||||
'template': '#tpl-host',
|
||||
'tagName': 'tr',
|
||||
|
||||
'modelEvents': {
|
||||
'change': 'render',
|
||||
},
|
||||
});
|
||||
|
||||
var PoolView = Backbone.Marionette.CompositeView.extend({
|
||||
'template': '#tpl-pool',
|
||||
|
||||
'model': Pool,
|
||||
|
||||
'itemView': HostView,
|
||||
'itemViewContainer': 'tbody',
|
||||
|
||||
'initialize': function () {
|
||||
// Grab the collection of Hosts from the pool model.
|
||||
this.collection = this.model.get('hosts');
|
||||
},
|
||||
});
|
||||
|
||||
var PoolsView = Backbone.Marionette.CollectionView.extend({
|
||||
'itemView': PoolView,
|
||||
});
|
||||
|
||||
//--------------------------------------
|
||||
// Application.
|
||||
//--------------------------------------
|
||||
|
||||
var app = new Backbone.Marionette.Application();
|
||||
|
||||
app.addRegions({
|
||||
'main': '#region-main',
|
||||
});
|
||||
|
||||
app.addInitializer(function (pools) {
|
||||
app.main.show(
|
||||
new PoolsView({'collection': pools})
|
||||
);
|
||||
});
|
||||
|
||||
//--------------------------------------
|
||||
// Execution.
|
||||
//--------------------------------------
|
||||
|
||||
$(function () {
|
||||
var pools = new Pools(window.pools);
|
||||
app.start(pools);
|
||||
|
||||
function refresh()
|
||||
{
|
||||
$.ajax('?json').done(function (data, status, jqXHR) {
|
||||
pools.update($.parseJSON(data));
|
||||
});
|
||||
|
||||
window.setTimeout(refresh, 5000);
|
||||
}
|
||||
window.setTimeout(refresh, 5000);
|
||||
});
|
||||
}();
|
@ -1,83 +0,0 @@
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
!function ()
|
||||
{
|
||||
"use strict";
|
||||
|
||||
//--------------------------------------
|
||||
// Models & collections.
|
||||
//--------------------------------------
|
||||
|
||||
var Host = Backbone.Model.extend({});
|
||||
|
||||
//--------------------------------------
|
||||
// Views.
|
||||
//--------------------------------------
|
||||
|
||||
var HostView = Backbone.Marionette.ItemView.extend({
|
||||
'template': '#tpl-host',
|
||||
'className': 'row well',
|
||||
|
||||
'modelEvents': {
|
||||
'change': 'render',
|
||||
},
|
||||
});
|
||||
|
||||
//--------------------------------------
|
||||
// Application.
|
||||
//--------------------------------------
|
||||
|
||||
var app = new Backbone.Marionette.Application();
|
||||
|
||||
app.addRegions({
|
||||
'main': '#region-main',
|
||||
});
|
||||
|
||||
app.addInitializer(function (host) {
|
||||
app.main.show(
|
||||
new HostView({'model': host})
|
||||
);
|
||||
});
|
||||
|
||||
//--------------------------------------
|
||||
// Execution.
|
||||
//--------------------------------------
|
||||
|
||||
$(function () {
|
||||
var host = new Host(window.host);
|
||||
app.start(host);
|
||||
|
||||
//$('#tab-host a:[href="#general"]').tab('show');
|
||||
|
||||
function refresh()
|
||||
{
|
||||
$.ajax('?json').done(function (data, status, jqXHR) {
|
||||
host.set($.parseJSON(data));
|
||||
});
|
||||
|
||||
window.setTimeout(refresh, 5000);
|
||||
}
|
||||
window.setTimeout(refresh, 5000);
|
||||
});
|
||||
}();
|
@ -1,123 +0,0 @@
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
!function ()
|
||||
{
|
||||
"use strict";
|
||||
|
||||
//--------------------------------------
|
||||
// Models & collections.
|
||||
//--------------------------------------
|
||||
|
||||
var SR = Backbone.Model.extend({});
|
||||
var SRs = Backbone.Collection.extend({
|
||||
'model': SR,
|
||||
});
|
||||
|
||||
function updateSRs()
|
||||
{
|
||||
var raw = this.get('SRs');
|
||||
var col = this.previous('SRs');
|
||||
col.update(raw);
|
||||
this.set('SRs', col, {'silent': true});
|
||||
}
|
||||
var Pool = Backbone.Model.extend({
|
||||
'initialize': function () {
|
||||
var SRs_ = this.get('SRs');
|
||||
if (SRs_ instanceof Array)
|
||||
{
|
||||
this.set('SRs', new SRs(SRs_), {'silent': true});
|
||||
}
|
||||
this.on('change:SRs', updateSRs, this);
|
||||
},
|
||||
});
|
||||
var Pools = Backbone.Collection.extend({
|
||||
'model': Pool,
|
||||
});
|
||||
|
||||
//--------------------------------------
|
||||
// Views.
|
||||
//--------------------------------------
|
||||
|
||||
var SRView = Backbone.Marionette.ItemView.extend({
|
||||
'template': '#tpl-storage',
|
||||
'tagName': 'tr',
|
||||
|
||||
'modelEvents': {
|
||||
'change': 'render',
|
||||
},
|
||||
});
|
||||
|
||||
var PoolView = Backbone.Marionette.CompositeView.extend({
|
||||
'template': '#tpl-pool',
|
||||
|
||||
'model': Pool,
|
||||
|
||||
'itemView': SRView,
|
||||
'itemViewContainer': 'tbody',
|
||||
|
||||
'initialize': function () {
|
||||
// Grab the collection of SRs from the pool model.
|
||||
this.collection = this.model.get('SRs');
|
||||
},
|
||||
});
|
||||
|
||||
var PoolsView = Backbone.Marionette.CollectionView.extend({
|
||||
'itemView': PoolView,
|
||||
});
|
||||
|
||||
//--------------------------------------
|
||||
// Application.
|
||||
//--------------------------------------
|
||||
|
||||
var app = new Backbone.Marionette.Application();
|
||||
|
||||
app.addRegions({
|
||||
'main': '#region-main',
|
||||
});
|
||||
|
||||
app.addInitializer(function (pools) {
|
||||
app.main.show(
|
||||
new PoolsView({'collection': pools})
|
||||
);
|
||||
});
|
||||
|
||||
//--------------------------------------
|
||||
// Execution.
|
||||
//--------------------------------------
|
||||
|
||||
$(function () {
|
||||
var pools = new Pools(window.pools);
|
||||
app.start(pools);
|
||||
|
||||
function refresh()
|
||||
{
|
||||
$.ajax('?json').done(function (data, status, jqXHR) {
|
||||
pools.update($.parseJSON(data));
|
||||
});
|
||||
|
||||
window.setTimeout(refresh, 5000);
|
||||
}
|
||||
window.setTimeout(refresh, 5000);
|
||||
});
|
||||
}();
|
@ -1,123 +0,0 @@
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
!function ()
|
||||
{
|
||||
"use strict";
|
||||
|
||||
//--------------------------------------
|
||||
// Models & collections.
|
||||
//--------------------------------------
|
||||
|
||||
var Template = Backbone.Model.extend({});
|
||||
var Templates = Backbone.Collection.extend({
|
||||
'model': Template,
|
||||
});
|
||||
|
||||
function updateTemplates()
|
||||
{
|
||||
var raw = this.get('templates');
|
||||
var col = this.previous('templates');
|
||||
col.update(raw);
|
||||
this.set('templates', col, {'silent': true});
|
||||
}
|
||||
var Pool = Backbone.Model.extend({
|
||||
'initialize': function () {
|
||||
var templates = this.get('templates');
|
||||
if (templates instanceof Array)
|
||||
{
|
||||
this.set('templates', new Templates(templates), {'silent': true});
|
||||
}
|
||||
this.on('change:templates', updateTemplates, this);
|
||||
},
|
||||
});
|
||||
var Pools = Backbone.Collection.extend({
|
||||
'model': Pool,
|
||||
});
|
||||
|
||||
//--------------------------------------
|
||||
// Views.
|
||||
//--------------------------------------
|
||||
|
||||
var TemplateView = Backbone.Marionette.ItemView.extend({
|
||||
'template': '#tpl-template',
|
||||
'tagName': 'tr',
|
||||
|
||||
'modelEvents': {
|
||||
'change': 'render',
|
||||
},
|
||||
});
|
||||
|
||||
var PoolView = Backbone.Marionette.CompositeView.extend({
|
||||
'template': '#tpl-pool',
|
||||
|
||||
'model': Pool,
|
||||
|
||||
'itemView': TemplateView,
|
||||
'itemViewContainer': 'tbody',
|
||||
|
||||
'initialize': function () {
|
||||
// Grab the collection of VMs from the pool model.
|
||||
this.collection = this.model.get('templates');
|
||||
},
|
||||
});
|
||||
|
||||
var PoolsView = Backbone.Marionette.CollectionView.extend({
|
||||
'itemView': PoolView,
|
||||
});
|
||||
|
||||
//--------------------------------------
|
||||
// Application.
|
||||
//--------------------------------------
|
||||
|
||||
var app = new Backbone.Marionette.Application();
|
||||
|
||||
app.addRegions({
|
||||
'main': '#region-main',
|
||||
});
|
||||
|
||||
app.addInitializer(function (pools) {
|
||||
app.main.show(
|
||||
new PoolsView({'collection': pools})
|
||||
);
|
||||
});
|
||||
|
||||
//--------------------------------------
|
||||
// Execution.
|
||||
//--------------------------------------
|
||||
|
||||
$(function () {
|
||||
var pools = new Pools(window.pools);
|
||||
app.start(pools);
|
||||
|
||||
function refresh()
|
||||
{
|
||||
$.ajax('?json').done(function (data, status, jqXHR) {
|
||||
pools.update($.parseJSON(data));
|
||||
});
|
||||
|
||||
window.setTimeout(refresh, 5000);
|
||||
}
|
||||
window.setTimeout(refresh, 5000);
|
||||
});
|
||||
}();
|
@ -1,123 +0,0 @@
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
!function ()
|
||||
{
|
||||
"use strict";
|
||||
|
||||
//--------------------------------------
|
||||
// Models & collections.
|
||||
//--------------------------------------
|
||||
|
||||
var Vm = Backbone.Model.extend({});
|
||||
var Vms = Backbone.Collection.extend({
|
||||
'model': Vm,
|
||||
});
|
||||
|
||||
function updateVms()
|
||||
{
|
||||
var raw = this.get('vms');
|
||||
var col = this.previous('vms');
|
||||
col.update(raw);
|
||||
this.set('vms', col, {'silent': true});
|
||||
}
|
||||
var Host = Backbone.Model.extend({
|
||||
'initialize': function () {
|
||||
var vms = this.get('vms');
|
||||
if (vms instanceof Array)
|
||||
{
|
||||
this.set('vms', new Vms(vms), {'silent': true});
|
||||
}
|
||||
this.on('change:vms', updateVms, this);
|
||||
},
|
||||
});
|
||||
var Hosts = Backbone.Collection.extend({
|
||||
'model': Host,
|
||||
});
|
||||
|
||||
//--------------------------------------
|
||||
// Views.
|
||||
//--------------------------------------
|
||||
|
||||
var VmView = Backbone.Marionette.ItemView.extend({
|
||||
'template': '#tpl-vm',
|
||||
'tagName': 'tr',
|
||||
|
||||
'modelEvents': {
|
||||
'change': 'render',
|
||||
},
|
||||
});
|
||||
|
||||
var HostView = Backbone.Marionette.CompositeView.extend({
|
||||
'template': '#tpl-host',
|
||||
|
||||
'model': Host,
|
||||
|
||||
'itemView': VmView,
|
||||
'itemViewContainer': 'tbody',
|
||||
|
||||
'initialize': function () {
|
||||
// Grab the collection of VMs from the host model.
|
||||
this.collection = this.model.get('vms');
|
||||
},
|
||||
});
|
||||
|
||||
var HostsView = Backbone.Marionette.CollectionView.extend({
|
||||
'itemView': HostView,
|
||||
});
|
||||
|
||||
//--------------------------------------
|
||||
// Application.
|
||||
//--------------------------------------
|
||||
|
||||
var app = new Backbone.Marionette.Application();
|
||||
|
||||
app.addRegions({
|
||||
'main': '#region-main',
|
||||
});
|
||||
|
||||
app.addInitializer(function (hosts) {
|
||||
app.main.show(
|
||||
new HostsView({'collection': hosts})
|
||||
);
|
||||
});
|
||||
|
||||
//--------------------------------------
|
||||
// Execution.
|
||||
//--------------------------------------
|
||||
|
||||
$(function () {
|
||||
var hosts = new Hosts(window.hosts);
|
||||
app.start(hosts);
|
||||
|
||||
function refresh()
|
||||
{
|
||||
$.ajax('?json').done(function (data, status, jqXHR) {
|
||||
hosts.update($.parseJSON(data));
|
||||
});
|
||||
|
||||
window.setTimeout(refresh, 5000);
|
||||
}
|
||||
window.setTimeout(refresh, 5000);
|
||||
});
|
||||
}();
|
@ -1,83 +0,0 @@
|
||||
/**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
!function ()
|
||||
{
|
||||
"use strict";
|
||||
|
||||
//--------------------------------------
|
||||
// Models & collections.
|
||||
//--------------------------------------
|
||||
|
||||
var Vm = Backbone.Model.extend({});
|
||||
|
||||
//--------------------------------------
|
||||
// Views.
|
||||
//--------------------------------------
|
||||
|
||||
var VmView = Backbone.Marionette.ItemView.extend({
|
||||
'template': '#tpl-vm',
|
||||
'className': 'row well',
|
||||
|
||||
'modelEvents': {
|
||||
'change': 'render',
|
||||
},
|
||||
});
|
||||
|
||||
//--------------------------------------
|
||||
// Application.
|
||||
//--------------------------------------
|
||||
|
||||
var app = new Backbone.Marionette.Application();
|
||||
|
||||
app.addRegions({
|
||||
'main': '#region-main',
|
||||
});
|
||||
|
||||
app.addInitializer(function (vm) {
|
||||
app.main.show(
|
||||
new VmView({'model': vm})
|
||||
);
|
||||
});
|
||||
|
||||
//--------------------------------------
|
||||
// Execution.
|
||||
//--------------------------------------
|
||||
|
||||
$(function () {
|
||||
var vm = new Vm(window.vm);
|
||||
app.start(vm);
|
||||
|
||||
//$('#tab-vm a:[href="#general"]').tab('show');
|
||||
|
||||
function refresh()
|
||||
{
|
||||
$.ajax('?json').done(function (data, status, jqXHR) {
|
||||
vm.set($.parseJSON(data));
|
||||
});
|
||||
|
||||
window.setTimeout(refresh, 5000);
|
||||
}
|
||||
window.setTimeout(refresh, 5000);
|
||||
});
|
||||
}();
|
@ -21,40 +21,9 @@
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
!function(xo, _, undefined)
|
||||
{
|
||||
!function(xo, _, undefined) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* [description]
|
||||
*
|
||||
* @todo Documentation
|
||||
*
|
||||
* @param {integer} size [description]
|
||||
* @param {string=} unit [description]
|
||||
* @param {integer=} base
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
xo.formatSize = function(size, unit, base)
|
||||
{
|
||||
size = +size;
|
||||
unit = (undefined !== unit) ? ''+unit : 'B';
|
||||
base = (undefined !== base) ? base|0 : 1024;
|
||||
|
||||
var powers = ['', 'K', 'M', 'G', 'T', 'P'];
|
||||
|
||||
for (var i = 0; size > base; ++i)
|
||||
{
|
||||
size /= base;
|
||||
}
|
||||
|
||||
// Maximum 1 decimals.
|
||||
size = ((size * 10)|0) / 10
|
||||
|
||||
return (size + powers[i] + unit);
|
||||
};
|
||||
|
||||
/**
|
||||
* [description]
|
||||
*
|
||||
@ -67,10 +36,9 @@
|
||||
*
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
xo.plop = function(values, ratio, total)
|
||||
{
|
||||
xo.plop = function(values, ratio, total) {
|
||||
var sum = _.reduce(values, function(sum, value) {
|
||||
return (sum + +value);
|
||||
return (sum + (+value));
|
||||
}, 0);
|
||||
|
||||
var avg = sum / _.size(values);
|
||||
@ -86,81 +54,5 @@
|
||||
});
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Documentation
|
||||
*
|
||||
* @param {integer} seconds Number of seconds of the duration.
|
||||
* @param {string=} precision Last unit that should be used
|
||||
* (Default is “seconds”).
|
||||
*
|
||||
* @return {string}
|
||||
*/
|
||||
xo.formatDuration = function(seconds, precision)
|
||||
{
|
||||
var units = [
|
||||
['years', 31556952], // 365.2425 days per year due to leap-years.
|
||||
['months', 2629746], // Divided by 12 months.
|
||||
['days', 86400], // 24 hours.
|
||||
['hours', 3600], // 60 minutes.
|
||||
['minutes', 60], // 60 seconds.
|
||||
['seconds', 1],
|
||||
];
|
||||
|
||||
var i = 0;
|
||||
var n = units.length;
|
||||
|
||||
// Find the first non null unit.
|
||||
while ((i < n) && (seconds < units[i][1]))
|
||||
{
|
||||
++i;
|
||||
}
|
||||
|
||||
var parts = [];
|
||||
for (; i < n; ++i)
|
||||
{
|
||||
var m = (seconds / units[i][1])|0;
|
||||
seconds %= units[i][1];
|
||||
|
||||
if (m)
|
||||
{
|
||||
parts.push(m + ' ' + units[i][0]);
|
||||
}
|
||||
|
||||
if (precision === units[i][0])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
n = parts.length - 1;
|
||||
|
||||
// Exactly one part.
|
||||
if (!n)
|
||||
{
|
||||
return parts[0];
|
||||
}
|
||||
|
||||
// More than one part.
|
||||
return (parts.slice(0, n).join(', ') + ' and ' + parts[n]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for xo.formatDuration() which format the duration
|
||||
* between a moment in the past and now.
|
||||
*
|
||||
* @param {integer} timestamp Unix timestamp of the past moment.
|
||||
* @param {string=} precision Last unit that should be used
|
||||
* (Default is “seconds”).
|
||||
*
|
||||
* @return {string}
|
||||
*/
|
||||
xo.formatDuration.fromNow = function(timestamp, precision)
|
||||
{
|
||||
return xo.formatDuration(
|
||||
Math.floor(Date.now() / 1000 - timestamp),
|
||||
precision
|
||||
);
|
||||
}
|
||||
}(window.xo = window.xo || {}, window._);
|
||||
};
|
||||
}(/* jshint expr:true */ window.xo = window.xo || {}, window._);
|
||||
|
623
public/js/xo.js
623
public/js/xo.js
@ -21,64 +21,593 @@
|
||||
* @package Xen Orchestra Web
|
||||
*/
|
||||
|
||||
!function ()
|
||||
{
|
||||
"use strict";
|
||||
// @todo Use Q promises.
|
||||
|
||||
$('.navbar a:first-child').tooltip({placement:'bottom'});
|
||||
(function (_, $, Backbone, undefined) {
|
||||
'use strict';
|
||||
|
||||
$('a[data-confirm]').click(function(e) {
|
||||
if (!window.confirm($(this).attr('data-confirm')))
|
||||
{
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Connection to XO.
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
$('form .enable-on-change[type="submit"]').each(function () {
|
||||
var submit = $(this).data('changed-items', 0);
|
||||
var handle = function (obj, changed) {
|
||||
obj = $(obj);
|
||||
if (!!obj.data('previous-state') === changed)
|
||||
var XO = function (url) {
|
||||
var xo = this;
|
||||
|
||||
// Identifier of the next request.
|
||||
var next_id = 0;
|
||||
|
||||
// Callbacks called when a response arrive.
|
||||
var callbacks = {};
|
||||
|
||||
// When the socket is closed, request are enqueued.
|
||||
var queue = [];
|
||||
|
||||
// Websocket used to connect to XO-Server.
|
||||
var socket = new WebSocket(url);
|
||||
|
||||
// Function used to send requests when the socket is opened.
|
||||
var send = function (method, params, callback) {
|
||||
var id = next_id++;
|
||||
|
||||
if (callback)
|
||||
{
|
||||
return;
|
||||
callbacks[id] = callback;
|
||||
}
|
||||
obj.data('previous-state', changed);
|
||||
|
||||
var counter = submit.data('changed-items') + (changed ? 1 : -1);
|
||||
submit.data('changed-items', counter);
|
||||
if (counter)
|
||||
{
|
||||
submit.removeAttr('disabled');
|
||||
}
|
||||
else
|
||||
{
|
||||
submit.attr('disabled', 'disabled');
|
||||
}
|
||||
socket.send(JSON.stringify({
|
||||
'jsonrpc': '2.0',
|
||||
'id': id,
|
||||
'method': method,
|
||||
'params': params || [],
|
||||
}));
|
||||
};
|
||||
|
||||
$(':text', submit.form).change(function () {
|
||||
handle(this, this.value !== this.defaultValue);
|
||||
// Function used to enqueue requests when the socket is closed.
|
||||
var enqueue = function (method, params, callback) {
|
||||
queue.push([method, params, callback]);
|
||||
};
|
||||
|
||||
// When the websocket opens, send any requests enqueued.
|
||||
socket.addEventListener('open', function () {
|
||||
// New requests are sent directly.
|
||||
xo.call = send;
|
||||
|
||||
var query;
|
||||
while ( (query = queue.shift()) )
|
||||
{
|
||||
send(query[0], query[1], query[2]);
|
||||
}
|
||||
});
|
||||
$('select', submit.form).change(function () {
|
||||
handle(this, !this.options[this.selectedIndex].defaultSelected);
|
||||
|
||||
// When the websocket closes, requests are not sent directly
|
||||
// but enqueud.
|
||||
socket.addEventListener('close', function () {
|
||||
xo.call = enqueue;
|
||||
});
|
||||
$(':checkbox', submit.form).change(function () {
|
||||
handle(this, this.checked !== this.defaultChecked);
|
||||
|
||||
// When a message is received, we call the corresponding
|
||||
// callback (if any).
|
||||
socket.addEventListener('message', function (event) {
|
||||
var response = JSON.parse(event.data.toString());
|
||||
|
||||
var id = response.id;
|
||||
var callback = callbacks[id];
|
||||
if (!callback)
|
||||
{
|
||||
// No callback associated: nothing to do.
|
||||
return;
|
||||
}
|
||||
delete callbacks[id];
|
||||
|
||||
var error = response.error;
|
||||
if (undefined !== error)
|
||||
{
|
||||
callback(error);
|
||||
return;
|
||||
}
|
||||
|
||||
var result = response.result;
|
||||
if (undefined === result)
|
||||
{
|
||||
/* jshint devel:true */
|
||||
console.warn(
|
||||
'a message with no error nor result has been received ',
|
||||
response
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
callback(null, result);
|
||||
});
|
||||
|
||||
// @todo What to do if there is an error in the websocket.
|
||||
socket.addEventListener('error', function (error) {
|
||||
console.error(error);
|
||||
});
|
||||
|
||||
// The default way to send a request is by enqueuing it.
|
||||
xo.call = enqueue;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Template helpers.
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
var template_helpers = {
|
||||
|
||||
/**
|
||||
* @todo Documentation
|
||||
*
|
||||
* @param {integer} seconds Number of seconds of the duration.
|
||||
* @param {integer=} precision Number of significant units to use.
|
||||
* (Default is 2).
|
||||
*
|
||||
* @return {string}
|
||||
*/
|
||||
'formatDuration': function(seconds, precision) {
|
||||
/* jshint bitwise:false */
|
||||
|
||||
var units = [
|
||||
['years', 31556952], // 365.2425 days per year due to leap-years.
|
||||
['months', 2629746], // Divided by 12 months.
|
||||
['days', 86400], // 24 hours.
|
||||
['hours', 3600], // 60 minutes.
|
||||
['minutes', 60], // 60 seconds.
|
||||
['seconds', 1],
|
||||
];
|
||||
|
||||
var i = 0;
|
||||
var n = units.length;
|
||||
|
||||
precision = precision ? precision|0 : 2;
|
||||
|
||||
// Find the first non null unit.
|
||||
while ((i < n) && (seconds < units[i][1]))
|
||||
{
|
||||
++i;
|
||||
}
|
||||
|
||||
var parts = [];
|
||||
for (; i < n; ++i)
|
||||
{
|
||||
var m = (seconds / units[i][1])|0;
|
||||
seconds %= units[i][1];
|
||||
|
||||
if (m)
|
||||
{
|
||||
parts.push(m + ' ' + units[i][0]);
|
||||
}
|
||||
|
||||
if (--precision <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
n = parts.length - 1;
|
||||
|
||||
// Exactly one part.
|
||||
if (!n)
|
||||
{
|
||||
return parts[0];
|
||||
}
|
||||
|
||||
// More than one part.
|
||||
return (parts.slice(0, n).join(', ') + ' and ' + parts[n]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper for xo.formatDuration() which format the duration
|
||||
* between a moment in the past and now.
|
||||
*
|
||||
* @param {integer} timestamp Unix timestamp of the past moment.
|
||||
* @param {string=} precision Last unit that should be used
|
||||
* (Default is “seconds”).
|
||||
*
|
||||
* @return {string}
|
||||
*/
|
||||
'formatDuration_fromNow': function(timestamp, precision) {
|
||||
return this.formatDuration(
|
||||
Math.floor(Date.now() / 1000 - timestamp),
|
||||
precision
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* [description]
|
||||
*
|
||||
* @todo Documentation
|
||||
*
|
||||
* @param {integer} size [description]
|
||||
* @param {string=} unit [description]
|
||||
* @param {integer=} base
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
'formatSize': function(size, unit, base){
|
||||
/* jshint bitwise:false */
|
||||
|
||||
size = +size;
|
||||
unit = (undefined !== unit) ? ''+unit : 'B';
|
||||
base = (undefined !== base) ? base|0 : 1024;
|
||||
|
||||
var powers = ['', 'K', 'M', 'G', 'T', 'P'];
|
||||
|
||||
for (var i = 0; size > base; ++i)
|
||||
{
|
||||
size /= base;
|
||||
}
|
||||
|
||||
// Maximum 1 decimals.
|
||||
size = ((size * 10)|0) / 10;
|
||||
|
||||
return (size + powers[i] + unit);
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
'link': function (label, path) {
|
||||
if (_.isArray(path))
|
||||
{
|
||||
path = path.join('/');
|
||||
}
|
||||
|
||||
return [
|
||||
'<a href="#'+ path +'">',
|
||||
label,
|
||||
'</a>',
|
||||
].join('');
|
||||
},
|
||||
|
||||
/**
|
||||
* [description]
|
||||
*
|
||||
* @todo Documentation
|
||||
*
|
||||
* @param {integer} percentage [description]
|
||||
* @param {object=} options [description]
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
'progressBar': function (percentage, options) {
|
||||
percentage = Math.round(percentage);
|
||||
if (percentage < 0)
|
||||
{
|
||||
percentage += 100;
|
||||
}
|
||||
|
||||
var label = (options && options.label) || (percentage +'%');
|
||||
|
||||
return [
|
||||
'<div class="progress progress-info progress-small" ',
|
||||
'title="'+ label +'">',
|
||||
'<div class="bar" style="width:'+ percentage +'%"></div>',
|
||||
'</div>',
|
||||
].join('');
|
||||
},
|
||||
|
||||
/**
|
||||
* [description]
|
||||
*
|
||||
* @todo Documentation
|
||||
*
|
||||
* @param {string} power_state [description]
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
'powerState': function () {
|
||||
var state_to_colors = {
|
||||
'Running': 'success',
|
||||
'Paused': 'info',
|
||||
'Halted': 'important',
|
||||
};
|
||||
|
||||
var state = this.power_state;
|
||||
|
||||
return [
|
||||
'<span class="label label-'+ state_to_colors[state] +'">',
|
||||
state,
|
||||
'</span>',
|
||||
].join('');
|
||||
},
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Models.
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Xen objects.
|
||||
//----------------------------------------------------------------
|
||||
|
||||
var Pool = Backbone.Model.extend({});
|
||||
var Host = Backbone.Model.extend({});
|
||||
var VM = Backbone.Model.extend({});
|
||||
|
||||
// var Network = Backbone.Model.extend({});
|
||||
// var SR = Backbone.Model.extend({});
|
||||
// var VDI = Backbone.Model.extend({});
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Collections.
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
var Pools = Backbone.Collection.extend({
|
||||
'model': Pool,
|
||||
});
|
||||
|
||||
/**
|
||||
* Blink Bell
|
||||
*
|
||||
* TODO: blink only when notifications.
|
||||
*/
|
||||
function blink(selector)
|
||||
{
|
||||
$(selector).fadeOut('slow', function () {
|
||||
$(this).fadeIn('slow', function () {
|
||||
blink(this);
|
||||
var Hosts = Backbone.Collection.extend({
|
||||
'model': Host,
|
||||
});
|
||||
|
||||
var VMs = Backbone.Collection.extend({
|
||||
'model': VM,
|
||||
});
|
||||
|
||||
// var Networks = Backbone.Collection.extend({
|
||||
// 'model': Network,
|
||||
// });
|
||||
|
||||
// var SRs = Backbone.Collection.extend({
|
||||
// 'model': SR,
|
||||
// });
|
||||
|
||||
// var VDIs = Backbone.Collection.extend({
|
||||
// 'model': VDI,
|
||||
// });
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Views.
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
var _serializeData = function () {
|
||||
function escape(object)
|
||||
{
|
||||
/* jshint laxbreak:true */
|
||||
|
||||
for (var property in object) {
|
||||
if (!object.hasOwnProperty(property))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var value = object[property];
|
||||
if (_.isString(value))
|
||||
{
|
||||
object[property] = _.escape(value);
|
||||
}
|
||||
else if (_.isObject(value)
|
||||
&& !(value instanceof Backbone.Collection)
|
||||
&& !(value instanceof Backbone.Model))
|
||||
{
|
||||
escape(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return function () {
|
||||
if (this.model)
|
||||
{
|
||||
var data = this.model.toJSON();
|
||||
escape(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
return {};
|
||||
};
|
||||
}();
|
||||
|
||||
var ItemView = Backbone.Marionette.ItemView.extend({
|
||||
'templateHelpers': template_helpers,
|
||||
|
||||
'constructor': function () {
|
||||
Backbone.Marionette.ItemView.apply(this, arguments);
|
||||
|
||||
if (this.model)
|
||||
{
|
||||
this.listenTo(this.model, 'change', this.render);
|
||||
}
|
||||
},
|
||||
|
||||
'serializeData': _serializeData,
|
||||
});
|
||||
|
||||
var CompositeView = Backbone.Marionette.CompositeView.extend({
|
||||
'templateHelpers': template_helpers,
|
||||
|
||||
'constructor': function () {
|
||||
Backbone.Marionette.CompositeView.apply(this, arguments);
|
||||
|
||||
if (this.model)
|
||||
{
|
||||
this.listenTo(this.model, 'change', this.render);
|
||||
}
|
||||
},
|
||||
|
||||
'serializeData': _serializeData,
|
||||
});
|
||||
|
||||
var CollectionView = Backbone.Marionette.CollectionView.extend({});
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
var StatsView = ItemView.extend({
|
||||
'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',
|
||||
|
||||
'initialize': function () {
|
||||
this.collection = this.model.get('hosts');
|
||||
},
|
||||
});
|
||||
var PoolView = CollectionView.extend({
|
||||
'itemView': HostsListView,
|
||||
});
|
||||
|
||||
// var VMsListItemView = ItemView.extend({
|
||||
// 'template': '#tpl-vms-list-item',
|
||||
// 'tagName': 'tr',
|
||||
// });
|
||||
// var VMsListView = CompositeView.extend({
|
||||
// 'template': '#tpl-vms-list',
|
||||
|
||||
// 'itemView': VMsListItemView,
|
||||
// 'itemViewContainer': 'tbody',
|
||||
// });
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Router.
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// @todo Puts this model in a controller.
|
||||
var stats;
|
||||
|
||||
var Router = Backbone.Router.extend({
|
||||
'routes': {
|
||||
'': 'home',
|
||||
|
||||
'hosts': 'hosts_listing',
|
||||
// 'hosts/:id': 'host_show',
|
||||
// //'hosts/:id/edit': 'host_edit',
|
||||
|
||||
// 'networks': 'networks_listing',
|
||||
// 'networks/:id': 'network_show',
|
||||
// //'networks/:id/edit': 'network_edit',
|
||||
|
||||
// 'storages': 'storages_listing',
|
||||
// 'storages/:id': 'storage_show',
|
||||
// //'storages/:id/edit': 'storage_edit',
|
||||
|
||||
// 'templates': 'templates_listing',
|
||||
// 'templates/:id': 'template_show',
|
||||
// //'templates/:id/edit': 'template_edit',
|
||||
|
||||
// 'vms': 'vms_listing',
|
||||
// 'vms/:id': 'vm_show',
|
||||
//'vms/:id/edit': 'vm_edit',
|
||||
|
||||
|
||||
// Default route.
|
||||
'*path': 'not_found',
|
||||
},
|
||||
|
||||
'home': function () {
|
||||
if (!stats)
|
||||
{
|
||||
stats = new Backbone.Model({
|
||||
'hosts': 'N/A',
|
||||
'vms': 'N/A',
|
||||
'running_vms': 'N/A',
|
||||
'memory': 'N/A',
|
||||
'vcpus': 'N/A',
|
||||
'vifs': 'N/A',
|
||||
'srs': 'N/A',
|
||||
});
|
||||
}
|
||||
app.main.show(new StatsView({'model': stats}));
|
||||
|
||||
// @todo Improve.
|
||||
xo.call('xo.getStats', null, function (error, result) {
|
||||
stats.set(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
//blink('#msg');
|
||||
}();
|
||||
},
|
||||
|
||||
'hosts_listing': function () {
|
||||
// @todo Gets data from XO-Server.
|
||||
var pools = new Pools([
|
||||
{
|
||||
'id': 0,
|
||||
'name': 'Pool 1',
|
||||
'hosts': new Hosts([
|
||||
{
|
||||
'id': 0,
|
||||
'name': 'Host 1',
|
||||
'description': 'no description',
|
||||
'memory': {
|
||||
'free': 1024,
|
||||
'total': 4096
|
||||
},
|
||||
'IPs': {},
|
||||
'start_time': 0,
|
||||
},
|
||||
{
|
||||
'id': 1,
|
||||
'name': 'Host 2',
|
||||
'description': 'no description',
|
||||
'memory': {
|
||||
'free': 3192,
|
||||
'total': 4096
|
||||
},
|
||||
'IPs': {},
|
||||
'start_time': Date.now()/1000 - 61,
|
||||
},
|
||||
]),
|
||||
},
|
||||
{
|
||||
'id': 1,
|
||||
'name': 'Pool 2',
|
||||
'hosts': new Hosts([
|
||||
{
|
||||
'id': 2,
|
||||
'name': 'Host 1',
|
||||
'description': 'no description',
|
||||
'memory': {
|
||||
'free': 1024,
|
||||
'total': 2048
|
||||
},
|
||||
'IPs': {},
|
||||
'start_time': 0,
|
||||
},
|
||||
]),
|
||||
},
|
||||
]);
|
||||
|
||||
app.main.show(new PoolView({
|
||||
'collection': pools
|
||||
}));
|
||||
},
|
||||
|
||||
'not_found': function (path) {
|
||||
alert('no such page: '+ path);
|
||||
this.navigate('', {'trigger': true});
|
||||
},
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Application.
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
var app = new Backbone.Marionette.Application();
|
||||
|
||||
app.addRegions({
|
||||
'main': '#reg-main',
|
||||
});
|
||||
|
||||
app.addInitializer(function () {
|
||||
/* jshint nonew:false */
|
||||
new Router();
|
||||
});
|
||||
|
||||
app.on('initialize:after', function () {
|
||||
Backbone.history.start();
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
var xo = new XO('ws://localhost:8080');
|
||||
|
||||
$(function () {
|
||||
app.start();
|
||||
});
|
||||
})(window._, window.jQuery, window.Backbone);
|
||||
|
@ -1,175 +0,0 @@
|
||||
{**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*}
|
||||
|
||||
{**
|
||||
* This is the base template and should not be used directly.
|
||||
*
|
||||
* See “normal.templet” and “wide.templet”.
|
||||
*}
|
||||
|
||||
{* HTML 5 Doctype *}
|
||||
<!DOCTYPE html>
|
||||
|
||||
{* The “no-js” class will be automatically removed if JavaScript is
|
||||
* available.
|
||||
*}
|
||||
<html lang="en" dir="ltr" class="no-js">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
{* Makes sure IE is using the last engine available. *}
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
|
||||
{* Replaces the “no-js” class by the “js” class if JavaScript
|
||||
* is available.
|
||||
*}
|
||||
<script>!function(d){{d.className=d.className.replace(/\bno-js\b/,'js')}(document.documentElement)</script>
|
||||
|
||||
{* HTML5 shim, for IE6-8 support of HTML5 elements. *}
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
{* (To confirm.) For smartphones and tablets: sets the page
|
||||
* width to the device width and prevents the page from being
|
||||
* zoomed in when going to landscape mode.
|
||||
*}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<title>{block title}Xen Orchestra{/block}</title>
|
||||
|
||||
<meta name="description" content="Web Interface for XCP" />
|
||||
<meta name="author" content="Olivier Lambert and Julien Fontanet" />
|
||||
|
||||
{* We use Bootstrap CSS. *}
|
||||
<link rel="stylesheet" href="{$base_path}/css/bootstrap.css" />
|
||||
|
||||
{* This font is used for icons. *}
|
||||
<link rel="stylesheet" href="{$base_path}/css/font-awesome.css" />
|
||||
|
||||
{* Our stylesheet and scripts. *}
|
||||
<link rel="stylesheet" href="{$base_path}/css/style.css" />
|
||||
<link rel="icon" type="image/png" href="{$base_path}/img/favicon.png" />
|
||||
|
||||
{* Children templates may used this block to add extra headers. *}
|
||||
{block extra_html_headers}{/block}
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a id="tour_home" class="brand" href="{$base_path}/">
|
||||
<img src="{$base_path}/img/bannerb.png" alt="Xen Orchestra" />
|
||||
</a>
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li class="divider-vertical"></li>
|
||||
<li id="tour_server" {if $server}class="active"{/if}>
|
||||
<a href="{url controller="servers"}"><i class="icon-cloud"></i> Server</a>
|
||||
</li>
|
||||
<li id="tour_vm" {if $vms}class="active"{/if}>
|
||||
<a href="{url controller="vms"}"><i class="icon-desktop"></i> Vm</a>
|
||||
</li>
|
||||
<li id="tour_misc" class="dropdown">
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
<i class="icon-cog"></i> Misc <b class="icon-caret-down"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="{url controller="templates"}"><i class="icon-file-alt"></i> Template</a></li>
|
||||
<li><a href="{url controller="storage"}"><i class="icon-hdd"></i> Storage</a></li>
|
||||
<li><a href="{url controller="network"}"><i class="icon-sitemap"></i> Network</a></li>
|
||||
<li class="disabled"><a href="#"><i class="icon-comment"></i> Logs</a></li>
|
||||
<li class="divider"></li>
|
||||
<li class="disabled"><a href="#"><i class="icon-asterisk"></i> Other</a></li>
|
||||
</ul>
|
||||
</ul>
|
||||
<ul class="nav pull-right">
|
||||
<li class="divider-vertical"></li>
|
||||
<li id="tour_setting" {if $admin}class="active"{/if}>
|
||||
<a title="Settings" href="{url controller="admin"}"><i class="icon-wrench"></i></a>
|
||||
</li>
|
||||
<li class="disabled">
|
||||
<a id="msg" href="#"><i class="icon-bell"></i></a>
|
||||
</li>
|
||||
|
||||
{**
|
||||
* Session.
|
||||
*}
|
||||
{if $user}
|
||||
<li>
|
||||
<a title="My profile" href="#"><i class="icon-user"></i> {$user}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a title="Log-Out" href="{url controller="home" action="session"}"> <i class="icon-signout"></i></a>
|
||||
</li>
|
||||
{else}
|
||||
<li id="tour_login" class="dropdown">
|
||||
<a class="dropdown-toggle" href="#" data-toggle="dropdown">
|
||||
<i class="icon-signin"></i> Log In <i class="icon-caret-down"></i>
|
||||
</a>
|
||||
<div class="dropdown-menu" style="padding: 15px; padding-bottom: 0px;">
|
||||
<form action="{url controller="home" action="session"}" method="post">
|
||||
<div class="input-prepend">
|
||||
<span class="add-on"><i class="icon-user"></i></span>
|
||||
<input class="span2" type="text" placeholder="User" name="name" required />
|
||||
</div>
|
||||
<div class="input-prepend">
|
||||
<span class="add-on"><i class="icon-key"></i></span>
|
||||
<input class="span2" type="password" placeholder="Password" name="password" required /><br /><br />
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="icon-signin icon-small"></i> Log In
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</li>
|
||||
{/if}
|
||||
|
||||
</ul>
|
||||
|
||||
<form id="tour_search" class="input-prepend navbar-search pull-right navbar-search" action="post">
|
||||
<span class="add-on"><i class="icon-search"></i></span>
|
||||
<input type="text" class="span2 inputIcon" placeholder="Search" disabled/>
|
||||
</form>
|
||||
</div>{* /.nav-collapse *}
|
||||
</div>{* /.container *}
|
||||
</div>{* /.navbar-inner *}
|
||||
</div>{* /.navbar *}
|
||||
|
||||
{block body}{/block}
|
||||
|
||||
{* JS Placed at the end of the document so the pages load faster *}
|
||||
<script src="{$base_path}/js/underscore.js"></script>
|
||||
<script src="{$base_path}/js/jquery.js"></script>
|
||||
<script src="{$base_path}/js/moment.js"></script>
|
||||
<script src="{$base_path}/js/bootstrap.js"></script>
|
||||
<script src="{$base_path}/js/xo.js"></script>
|
||||
<script src="{$base_path}/js/xo.helpers.js"></script>
|
||||
{block extra_scripts}{/block}
|
||||
</body>
|
||||
</html>
|
@ -1,46 +0,0 @@
|
||||
{**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*}
|
||||
|
||||
{extends "/_base.templet"}
|
||||
|
||||
{block title}Xen Orchestra - Home{/block}
|
||||
|
||||
{block body}
|
||||
<div class="row-fluid">
|
||||
<div class="span10 offset1 text-error">
|
||||
<h2>{if $error}{$error}{else}Unknown error{/if}</h2>
|
||||
<p>
|
||||
{if $message}
|
||||
{$message}
|
||||
{else}
|
||||
We are sorry but an unknown error just occured.
|
||||
{/if}
|
||||
</p>
|
||||
<p>
|
||||
You may {if $referer}go back to the <a href="{$referer}">previous page</a>
|
||||
{else}return to the <a href="{$base_path}/">homepage</a>{/if} or
|
||||
<a href="https://vates.fr/en/contacts.php">contact us</a> for more information.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
@ -1,46 +0,0 @@
|
||||
{**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*}
|
||||
|
||||
{extends "/_base.templet"}
|
||||
|
||||
{block title}Xen Orchestra - Admin{/block}
|
||||
|
||||
{block body}
|
||||
<div class="row-fluid">
|
||||
<div class="span2 offset1">
|
||||
<ul class="nav nav-list well">
|
||||
<li class="nav-header">Admin Panel</li>
|
||||
<li {if $dashboard}class="active"{/if}><a href="{url}">Dashboard</a></li>
|
||||
<li class="nav-header">Security</li>
|
||||
<li {if $menu_admin_users}class="active"{/if}><a href="{url action="users"}">Users</a></li>
|
||||
<li {if $groups}class="active"{/if}><a href="{url action="groups"}">Groups</a></li>
|
||||
<li {if $policies}class="active"{/if}><a href="{url action="policies"}">Policies</a></li>
|
||||
<li class="nav-header">XCP settings</li>
|
||||
<li {if $hosts}class="active"{/if}><a href="{url action="hosts"}">Hosts</a></li>
|
||||
<li {if $apps}class="active"{/if}><a href="{url action="apps"}">Apps</a></li>
|
||||
<li class="nav-header">Misc</li>
|
||||
<li {if $events}class="active"{/if}><a href="{url action="events"}">XO Events</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{block content}{/block}
|
||||
{/block body}
|
@ -1,31 +0,0 @@
|
||||
{**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*}
|
||||
|
||||
{extends "/admin/_base.templet"}
|
||||
|
||||
{block content}
|
||||
<div class="span8 well">
|
||||
<h3 class="center">Apps</h3>
|
||||
<p class="center">Here admin of apps</p>
|
||||
</div>
|
||||
{/block content}
|
@ -1,31 +0,0 @@
|
||||
{**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*}
|
||||
|
||||
{extends "/admin/_base.templet"}
|
||||
|
||||
{block content}
|
||||
<div class="span8 well">
|
||||
<h3 class="center">Events</h3>
|
||||
<p class="center">Here admin of events</p>
|
||||
</div>
|
||||
{/block content}
|
@ -1,31 +0,0 @@
|
||||
{**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*}
|
||||
|
||||
{extends "/admin/_base.templet"}
|
||||
|
||||
{block content}
|
||||
<div class="span8 well">
|
||||
<h3 class="center">Groups</h3>
|
||||
<p class="center">Here admin of groups</p>
|
||||
</div>
|
||||
{/block content}
|
@ -1,39 +0,0 @@
|
||||
{**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*}
|
||||
|
||||
{extends "/admin/_base.templet"}
|
||||
|
||||
{block content}
|
||||
<div class="span8">
|
||||
<div class="accordion-group"> <div class="accordion-heading"><a class="accordion-toggle" href="#item0" data-toggle="collapse"> Configured Hosts </a> </div>
|
||||
<div id="item0" class="collapse in">
|
||||
<div class="accordion-inner"> Cluster1 (single host)</div>
|
||||
<div class="accordion-inner"> Cluster2 (single host)</div>
|
||||
<div class="accordion-inner"> XenFr1 (pool master)</div>
|
||||
</div></div>
|
||||
<div class="accordion-group"> <div class="accordion-heading"> <a class="accordion-toggle" href="#item2" data-toggle="collapse"> Pool master failback </a> </div>
|
||||
<div id="item2" class="collapse">
|
||||
<div class="accordion-inner"> XenFr2 </div>
|
||||
</div></div>
|
||||
</div>
|
||||
{/block content}
|
@ -1,31 +0,0 @@
|
||||
{**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*}
|
||||
|
||||
{extends "/admin/_base.templet"}
|
||||
|
||||
{block content}
|
||||
<div class="span8 well">
|
||||
<h3 class="center">Dashboard</h3>
|
||||
<p class="center">Here some nice graphs and/or recap of XO</p>
|
||||
</div>
|
||||
{/block content}
|
@ -1,31 +0,0 @@
|
||||
{**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*}
|
||||
|
||||
{extends "/admin/_base.templet"}
|
||||
|
||||
{block content}
|
||||
<div class="span8 well">
|
||||
<h3 class="center">Policies</h3>
|
||||
<p class="center">Here admin of policies</p>
|
||||
</div>
|
||||
{/block content}
|
@ -1,85 +0,0 @@
|
||||
{**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*}
|
||||
|
||||
{**
|
||||
* @todo Disable fields for current user.
|
||||
*}
|
||||
|
||||
{extends "/admin/_base.templet"}
|
||||
|
||||
{block content}
|
||||
<div class="span8 well">
|
||||
<h2 class="center">Users</h2>
|
||||
|
||||
<h3>Existing</h3>
|
||||
<form action="{url action="users"}?a=update" method="post">
|
||||
<table class="table table-striped table-bordered table-hover table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Permission</th>
|
||||
<th>Delete?</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{foreach $users as $user_}
|
||||
<tr>
|
||||
<td><input type="text" value="{$user_.name}" disabled /></td>
|
||||
<td>
|
||||
<input type="hidden" name="old_perm[{$user_.id}]" value="{$user_.permission}" />
|
||||
<select name="new_perm[{$user_.id}]">
|
||||
{generateSelectOptions options=$permissions selected=$user_.permission}
|
||||
</select>
|
||||
</td>
|
||||
<td><input type="checkbox" name="delete[{$user_.id}]" /></td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
<button type="submit" class="btn btn-primary enable-on-change" disabled="disabled">
|
||||
<i class="icon-save"></i> Save changes
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<h3>Create</h3>
|
||||
<form action="{url action="users"}?a=create" method="post" autocomplete="off">
|
||||
<div class="input-prepend">
|
||||
<span class="add-on"><i class="icon-user"></i></span>
|
||||
<input type="text" placeholder="User" name="name" required />
|
||||
</div>
|
||||
<div class="input-prepend">
|
||||
<span class="add-on"><i class="icon-key"></i></span>
|
||||
<input type="password" placeholder="Password" name="password" required />
|
||||
</div>
|
||||
<div>
|
||||
<select name="permission">
|
||||
{generateSelectOptions options=$permissions selected="none"}
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="icon-plus"></i> Create user
|
||||
</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
{/block content}
|
@ -1,164 +0,0 @@
|
||||
{**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*}
|
||||
|
||||
{extends "/_base.templet"}
|
||||
|
||||
{block title}Xen Orchestra - Home{/block}
|
||||
|
||||
{block body}
|
||||
{if $connected}
|
||||
<div class="row-fluid">
|
||||
<div class="span10 offset1 hero-unit">
|
||||
<h2 class="center">XO Dashboard</h2>
|
||||
<div class="row-fluid offset1">
|
||||
<div class="row-fluid span3 center">
|
||||
<h2>{$stats.hosts}x <a href="{url controller="servers"}"><i class="icon-cloud icon-2x"></i></a></h2>
|
||||
<p>servers running</p>
|
||||
</div>
|
||||
<div class="row-fluid span3 center">
|
||||
<h2>{$stats.running_vms}x <a href="{url controller="vms"}"><i class="icon-desktop icon-2x"></i></a></h2>
|
||||
<p>of {$stats.vms} VMs running</p>
|
||||
</div>
|
||||
<div class="row-fluid span3 center">
|
||||
<h2>{$stats.srs}x <a href="{url controller="storage"}"><i class="icon-hdd icon-2x"></i></a></h2>
|
||||
<p>shared repositories</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-fluid offset1">
|
||||
<div class="row-fluid span3 center">
|
||||
<h2>{$stats.vcpus}x <i class="icon-dashboard icon-2x"></i></h2>
|
||||
<p>vCPUs used</p>
|
||||
</div>
|
||||
<div class="row-fluid span3 center">
|
||||
<h2>{$stats.memory}GB <i class="icon-tasks icon-2x"></i></h2>
|
||||
<p>of RAM allocated</p>
|
||||
</div>
|
||||
<div class="row-fluid span3 center">
|
||||
<h2>{$stats.vifs}x <i class="icon-sitemap icon-2x"></i></h2>
|
||||
<p>virtual interfaces up</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{else}
|
||||
<div class="modal hide fade" id="feature">
|
||||
<div class="modal-header"> <a class="close" data-dismiss="modal">×</a>
|
||||
<h3>Alpha version</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Sorry, it's not yet possible to configure new servers with the web interface. Please edit your xo-server configuration.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class="btn btn-info" data-dismiss="modal">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-fluid">
|
||||
<div class="span10 offset1 hero-unit">
|
||||
<h1 class="center">Welcome on XO!</h1>
|
||||
<p class="center">It seems you don't have any connected host.<br/>Add an XCP host or a Pool master, and start to use the magic of Xen Orchestra.</p><br/>
|
||||
<p class="center"><a class="btn btn-success btn-large" data-toggle="modal" href="#feature" ><i class="icon-plus"></i> Add server</a></p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span3 well offset1">
|
||||
<h2 class="center">Need help?</h2>
|
||||
<p>If you don't know how to start, please read the README first. Then, if you have further questions, please read the FAQ on the project website.
|
||||
</p><br/>
|
||||
<p class="center"><a class="btn btn-info btn-large start" href="#" ><i class="icon-info-sign"></i> Start tour</a></p>
|
||||
</div>
|
||||
<div class="span4 well">
|
||||
<h2 class="center">About us</h2>
|
||||
<p>We are the team behind XO, we are Vates! We create Open Source products and we offer commercial support for Xen and Xen Orchestra. This project is Open Source (AGPL), everyone is welcome aboard!</p><br/>
|
||||
<p class="center"><a class="btn btn-large" href="http://vates.fr"><i class="icon-circle-arrow-right"></i> Go on our website!</a></p>
|
||||
</div>
|
||||
<div class="span3 well">
|
||||
<h2 class="center">Get involved!</h2>
|
||||
<p>You want a specific feature in XO? Report a bug? Go to our project website, read the FAQ and get involved in the project!</p><br/>
|
||||
<p class="center"><a class="btn btn-success btn-large" href="http://xen-orchestra.com"><i class="icon-beaker"></i> Project page</a></p>
|
||||
</div>
|
||||
</div>
|
||||
{/block body}
|
||||
|
||||
{block extra_scripts}
|
||||
<script src="{$base_path}/js/bootstrap-tour.js"></script>
|
||||
<script src="{$base_path}/js/jquery.cookie.js"></script>
|
||||
<script>
|
||||
"use strict";
|
||||
var tour = new Tour();
|
||||
tour.addStep({{
|
||||
element: "#tour_home",
|
||||
placement: "bottom",
|
||||
title: "Welcome on XO",
|
||||
content: "Here is the home of Xen-Orchestra."
|
||||
});
|
||||
tour.addStep({{
|
||||
element: "#tour_server",
|
||||
placement: "bottom",
|
||||
title: "Servers and stuff",
|
||||
content: "Server gives you a global view on your XCP hosts."
|
||||
});
|
||||
tour.addStep({{
|
||||
element: "#tour_vm",
|
||||
placement: "bottom",
|
||||
title: "VMs management",
|
||||
content: "The big part of XO: where are you goddamn VM? That's the spot."
|
||||
});
|
||||
tour.addStep({{
|
||||
element: "#tour_misc",
|
||||
placement: "bottom",
|
||||
title: "Rest of the world",
|
||||
content: "All other non-critical things for everyday exploitation."
|
||||
});
|
||||
tour.addStep({{
|
||||
element: "#tour_search",
|
||||
placement: "bottom",
|
||||
title: "Quick search",
|
||||
content: "In a future release, you'll be able to find tags, users, VMs or servers easily with this search bar."
|
||||
});
|
||||
tour.addStep({{
|
||||
element: "#tour_setting",
|
||||
placement: "bottom",
|
||||
title: "Configuration",
|
||||
content: "Here you can create users, but be careful to login before! More in the next version."
|
||||
});
|
||||
tour.addStep({{
|
||||
element: "#msg",
|
||||
placement: "bottom",
|
||||
title: "Notifications",
|
||||
content: "In a future release, you'll see a blinking bell when a important message appears."
|
||||
});
|
||||
tour.addStep({{
|
||||
element: "#tour_login",
|
||||
placement: "bottom",
|
||||
title: "Login form",
|
||||
content: "admin/admin is the default login. Don't forget to change it quickly! ;)"
|
||||
});
|
||||
$(document).on("click", ".start", function (e) {{
|
||||
e.preventDefault();
|
||||
tour.restart();
|
||||
$(".alert").alert("close");
|
||||
});
|
||||
</script>
|
||||
{/block}
|
@ -1,58 +0,0 @@
|
||||
{**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*}
|
||||
|
||||
{extends "/_base.templet"}
|
||||
|
||||
{block title}Logs overview{/block}
|
||||
|
||||
{block body}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<h3 class="center">Logs overview</h3>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
{/block body}
|
@ -1,78 +0,0 @@
|
||||
{**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*}
|
||||
|
||||
{extends "/_base.templet"}
|
||||
|
||||
{block title}Network Overview{/block}
|
||||
|
||||
{block extra_scripts}
|
||||
<script src="{$base_path}/js/backbone.js"></script>
|
||||
<script src="{$base_path}/js/marionette.js"></script>
|
||||
<script>
|
||||
var pools = {$pools|json};
|
||||
</script>
|
||||
<script src="{$base_path}/js/network/index.js"></script>
|
||||
{/block}
|
||||
|
||||
{block body}
|
||||
<script type="text/html" id="tpl-pool">
|
||||
<table class="table table-hover table-bordered">
|
||||
<caption><h3 class="center"><%= name %></h3></caption>
|
||||
<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>
|
||||
</tbody>
|
||||
</table>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tpl-network">
|
||||
<td><i class="icon-sitemap"></i> <%= name %></td>
|
||||
<td><%= speed %></td>
|
||||
<td><%= duplex ? 'Yes' : 'No' %></td>
|
||||
<td><%= IP ? IP : '<i>none</i>' %></td>
|
||||
<td class="mac-address"><%= MAC %></td>
|
||||
<td><%= vendor %> <%= device %></td>
|
||||
<td><%
|
||||
if (currently_attached)
|
||||
{{
|
||||
%><span class="label label-success">Connected</span></td><%
|
||||
}
|
||||
else
|
||||
{{
|
||||
%><span class="label label-important">Not connected</span></td><%
|
||||
} %>
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<div class="row" id="region-main"></div>
|
||||
</div>
|
||||
{/block body}
|
@ -1,74 +0,0 @@
|
||||
{**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*}
|
||||
|
||||
{extends "/_base.templet"}
|
||||
|
||||
{block title}Pool overview{/block}
|
||||
|
||||
{block body}
|
||||
<div class="row-fluid">
|
||||
<div class="span2 offset1">
|
||||
<ul class="nav nav-list well">
|
||||
<li class="nav-header">Pool Manager</li>
|
||||
<li class="active"><a href="#">Overview</a></li>
|
||||
<li class="nav-header">Management</li>
|
||||
<li><a href="#">New pool</a></li>
|
||||
<li><a href="#">Add server</a></li>
|
||||
<li class="nav-header">Connected pools</li>
|
||||
<li><a href="#"><i class="icon-cloud"></i> Dev Pool</a></li>
|
||||
<li><a href="#"><i class="icon-cloud"></i> Prod Pool</a></li>
|
||||
<li><a href="#"><i class="icon-cloud"></i> Test Pool</a></li>
|
||||
<li class="nav-header">Misc</li>
|
||||
<li><a href="#">Pool Events</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="span8">
|
||||
<h2 class="center">Pool overview</h2>
|
||||
<table class="table table-bordered table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Servers</th>
|
||||
<th>Storage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Dev Pool</td>
|
||||
<td>Cluster1, Cluster2</td>
|
||||
<td>NFS virtual disk storage</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Prod Pool</td>
|
||||
<td>Cluster3, Cluster4, Cluster5, Cluster6</td>
|
||||
<td>NFS virtual disk storage</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Test Pool</td>
|
||||
<td>Cluster10, Cluster11</td>
|
||||
<td>NFS virtual disk storage</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{/block body}
|
@ -1,75 +0,0 @@
|
||||
{**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*}
|
||||
|
||||
{extends "/_base.templet"}
|
||||
|
||||
{block title}Server overview{/block}
|
||||
|
||||
{block extra_scripts}
|
||||
<script src="{$base_path}/js/backbone.js"></script>
|
||||
<script src="{$base_path}/js/marionette.js"></script>
|
||||
<script>
|
||||
var pools = {$pools|json};
|
||||
</script>
|
||||
<script src="{$base_path}/js/servers/index.js"></script>
|
||||
{/block}
|
||||
|
||||
{block body}
|
||||
<script type="text/html" id="tpl-pool">
|
||||
<table class="table table-bordered table-hover table-striped">
|
||||
<caption><h3 class="center"><%= name %></h3></caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<th>Memory</th>
|
||||
<th>Addresses</th>
|
||||
<th>Uptime</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tpl-host">
|
||||
<% var mem_usage = 100-Math.round(100*memory.free/memory.total) %>
|
||||
<td><a href="{$base_path}/servers/<%= id %>"><%= name %></a></td>
|
||||
<td><%= description || "<i>none</i>" %></td>
|
||||
<td>
|
||||
<div class="progress progress-info progress-small" title="<%= mem_usage %>%">
|
||||
<div class="bar" style="width: <%= mem_usage %>%"></div>
|
||||
</div>
|
||||
</td>
|
||||
<td><%= IPs.length ? IPs.join(', ') : '<i>none</i>' %></td>
|
||||
<td><%=
|
||||
start_time
|
||||
? Math.round((Date.now()/1000-start_time)/8640)/10 + ' days'
|
||||
: '<i>N/A</i>'
|
||||
%></td>
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<div class="row" id="region-main"></div>
|
||||
</div>
|
||||
{/block body}
|
@ -1,273 +0,0 @@
|
||||
{**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*}
|
||||
|
||||
{extends "/_base.templet"}
|
||||
|
||||
{block title}Server overview{/block}
|
||||
|
||||
{block extra_scripts}
|
||||
<script src="{$base_path}/js/backbone.js"></script>
|
||||
<script src="{$base_path}/js/marionette.js"></script>
|
||||
<script>
|
||||
var host = {$host|json};
|
||||
</script>
|
||||
<script src="{$base_path}/js/servers/show.js"></script>
|
||||
{/block}
|
||||
|
||||
{block body}
|
||||
<script type="text/html" id="tpl-host">
|
||||
<h3 class="center"><%= name %></h3>
|
||||
<ul id="tab" 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 id="myTabContent" class="tab-content">
|
||||
<div class="tab-pane fade in active" id="general">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Name:</dt>
|
||||
<dd><%= name %></dd>
|
||||
<dt>Description:</dt>
|
||||
<dd><%= description %></dd>
|
||||
<dt>Pool master:</dt>
|
||||
<dd><%= is_pool_master ? 'Yes' : 'No' %></dd>
|
||||
<dt>Enabled:</dt>
|
||||
<dd><%= enabled ? 'Yes' : 'No' %></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 ? xo.formatDuration.fromNow(start_time, 'minutes') : '<i>N/A</i>' %></dd>
|
||||
<dt>Toolstack uptime:</dt>
|
||||
<dd><%= tool_stack_start_time ? xo.formatDuration.fromNow(tool_stack_start_time, 'minutes') : '<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>
|
||||
</div>
|
||||
<div class="tab-pane fade" 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 = xo.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 %>%;">
|
||||
<a href="{$base_path}/vms/<%= VM_uuid %>"><%= VM.name %></a><br/>
|
||||
(<%= VM_mem %>)
|
||||
</div><%
|
||||
}
|
||||
} %>
|
||||
</div>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Total memory:</dt>
|
||||
<dd><%= xo.formatSize(memory.total) %></dd>
|
||||
<dt>Currently used:</dt>
|
||||
<dd><%= xo.formatSize(memory.total-memory.free) %></dd>
|
||||
<dt>Available memory:</dt>
|
||||
<dd><%= xo.formatSize(memory.free) %></dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="tab-pane fade" 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) %>% (<%= xo.formatSize(SR.used) %> used)</td>
|
||||
<td><%= xo.formatSize(SR.total) %></td>
|
||||
<td><%= xo.formatSize(SR.allocated) %></td>
|
||||
</tr><%
|
||||
} %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="tab-pane fade" 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>
|
||||
</div>
|
||||
{* @todo
|
||||
<div class="tab-pane fade" id="console">
|
||||
<p>Not yet implemented.</p>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="perfs">
|
||||
<p>Not yet implemented.</p>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="alerts">
|
||||
<p>Not yet implemented.</p>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="other">
|
||||
<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>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="logs">
|
||||
<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>
|
||||
</div> *}
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$('#tab a').click(function (e) {{
|
||||
e.preventDefault();
|
||||
$(this).tab('show');
|
||||
});
|
||||
</<% %>script>
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<div class="row" id="region-main"></div>
|
||||
</div>
|
||||
{/block body}
|
@ -1,70 +0,0 @@
|
||||
{**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*}
|
||||
|
||||
{extends "/_base.templet"}
|
||||
|
||||
{block title}Storage Overview{/block}
|
||||
|
||||
{block extra_scripts}
|
||||
<script src="{$base_path}/js/backbone.js"></script>
|
||||
<script src="{$base_path}/js/marionette.js"></script>
|
||||
<script>
|
||||
var pools = {$pools|json};
|
||||
</script>
|
||||
<script src="{$base_path}/js/storage/index.js"></script>
|
||||
{/block}
|
||||
|
||||
{block body}
|
||||
<script type="text/html" id="tpl-pool">
|
||||
<table class="table table-hover table-bordered">
|
||||
<caption><h3 class="center"><%= name %></h3></caption>
|
||||
<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>
|
||||
</tbody>
|
||||
</table>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tpl-storage">
|
||||
<td><i class="icon-hdd"></i> <%= name %></td>
|
||||
<td><%= description %></td>
|
||||
<td><%= type %></td>
|
||||
<td><%= shared ? 'Yes' : 'No' %></td>
|
||||
<td><%= Math.round(100*used/total) %>% (<%= xo.formatSize(used) %> used)</td>
|
||||
<td><%= xo.formatSize(total) %></td>
|
||||
<td><%= xo.formatSize(allocated) %></td>
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<div class="row" id="region-main"></div>
|
||||
</div>
|
||||
{/block body}
|
@ -1,61 +0,0 @@
|
||||
{**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*}
|
||||
|
||||
{extends "/_base.templet"}
|
||||
|
||||
{block title}Templates{/block}
|
||||
|
||||
{block extra_scripts}
|
||||
<script src="{$base_path}/js/backbone.js"></script>
|
||||
<script src="{$base_path}/js/marionette.js"></script>
|
||||
<script>
|
||||
var pools = {$pools|json};
|
||||
</script>
|
||||
<script src="{$base_path}/js/templates/index.js"></script>
|
||||
{/block}
|
||||
|
||||
{block body}
|
||||
<script type="text/html" id="tpl-pool">
|
||||
<table class="table table-hover table-bordered">
|
||||
<caption><%= name || '<i>unknown</i>' %></caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tpl-template">
|
||||
<td><i class="icon-file-alt"></i> <%= name %></td>
|
||||
<td><%= description %></td>
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<h3 class="center">Templates overview</h3>
|
||||
<div class="row" id="region-main"></div>
|
||||
</div>
|
||||
{/block body}
|
@ -1,102 +0,0 @@
|
||||
{**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*}
|
||||
|
||||
{extends "/_base.templet"}
|
||||
|
||||
{block title}VMs Overview{/block}
|
||||
|
||||
{block extra_scripts}
|
||||
<script src="{$base_path}/js/backbone.js"></script>
|
||||
<script src="{$base_path}/js/marionette.js"></script>
|
||||
<script>
|
||||
var hosts = {$hosts|json};
|
||||
</script>
|
||||
<script src="{$base_path}/js/vms/index.js"></script>
|
||||
{/block}
|
||||
|
||||
{block body}
|
||||
<script type="text/html" id="tpl-host">
|
||||
<table class="table table-striped table-bordered table-hover" id="<%= id %>">
|
||||
<caption><h3 class="center">
|
||||
<% if (name)
|
||||
{{
|
||||
%><a href="{$base_path}/servers/<%= id %>"><%= name %></a><%
|
||||
}
|
||||
else
|
||||
{{
|
||||
%><i>No hosts</i><%
|
||||
} %>
|
||||
</h3></caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
{*<th>CPU Usage</th>*}
|
||||
<th>Memory</th>
|
||||
<th>Disk</th>
|
||||
<th>Network</th>
|
||||
<th>Address</th>
|
||||
<th>Uptime</th>
|
||||
<th>State</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="tpl-vm">
|
||||
<td><a href="{$base_path}/vms/<%= id %>"><%= name_label %></a></td>
|
||||
<td><%= name_description %></td>
|
||||
{*<td><div class="progress progress-info progress-small"><div class="bar" style="width: 10%;"></div></div></td>*}
|
||||
<td><%
|
||||
if (used_memory)
|
||||
{{
|
||||
var memory = used_memory / total_memory;
|
||||
%><div class="progress progress-info progress-small"><div class="bar" style="width: <%= memory %>%;"></div></div></td><%
|
||||
}
|
||||
else
|
||||
{{
|
||||
%><%= xo.formatSize(total_memory) %><%
|
||||
}
|
||||
%>
|
||||
<td><%= VBDs %></td>
|
||||
<td><%= VIFs %></td>
|
||||
<td><%= _.values(networks).join(', ') %></td>
|
||||
<td><%=
|
||||
start_time
|
||||
? Math.round((Date.now()/1000-start_time)/8640)/10 + ' days'
|
||||
: '<i>N/A</i>'
|
||||
%></td>
|
||||
<td><span class="label label-<%
|
||||
var state_to_colors = {{
|
||||
'Running': 'success',
|
||||
'Paused': 'info',
|
||||
'Halted': 'important',
|
||||
};
|
||||
%><%= state_to_colors[power_state] %>"><%= power_state %></span></td>
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<div class="row" id="region-main"></div>
|
||||
</div>
|
||||
{/block body}
|
@ -1,291 +0,0 @@
|
||||
{**
|
||||
* This file is a part of Xen Orchestra Web.
|
||||
*
|
||||
* Xen Orchestra Web is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Xen Orchestra Web is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Xen Orchestra Web. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Olivier Lambert <olivier.lambert@vates.fr>
|
||||
* @license http://www.gnu.org/licenses/agpl-3.0-standalone.html GNU AGPLv3
|
||||
*
|
||||
* @package Xen Orchestra Web
|
||||
*}
|
||||
|
||||
{extends "/_base.templet"}
|
||||
|
||||
{block title}VM overview{/block}
|
||||
|
||||
{block extra_scripts}
|
||||
<script src="{$base_path}/js/backbone.js"></script>
|
||||
<script src="{$base_path}/js/marionette.js"></script>
|
||||
<script>
|
||||
var vm = {$vm|json};
|
||||
</script>
|
||||
<script src="{$base_path}/js/vms/show.js"></script>
|
||||
{/block}
|
||||
|
||||
{block body}
|
||||
<script type="text/html" id="tpl-vm">
|
||||
<h3 class="center"><%= name %></h3>
|
||||
<ul id="tab" class="nav nav-tabs">
|
||||
<li class="active"><a href="#general"><i class="icon-home"></i> General</a></li>
|
||||
<li><a href="#cpu"><i class="icon-dashboard"></i> CPU</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>
|
||||
<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">
|
||||
{* @todo<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="#snapshots"><i class="icon-camera"></i> Snapshots</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 id="myTabContent" class="tab-content">
|
||||
<div class="tab-pane fade in active" id="general">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>State:</dt>
|
||||
<dd><span class="label label-<%
|
||||
var state_to_colors = {{
|
||||
'Running': 'success',
|
||||
'Paused': 'info',
|
||||
'Halted': 'important',
|
||||
};
|
||||
%><%= state_to_colors[power_state] %>"><%= power_state %></span></dd>
|
||||
<dt>Name:</dt>
|
||||
<dd><%= name %></dd>
|
||||
<dt>Description:</dt>
|
||||
<dd><%= description || '<i>none</i>' %></dd>
|
||||
<dt>Tags:</dt>
|
||||
<dd><%= tags.length ? tags.join(", ") : "<i>none</i>" %></dd>
|
||||
{* @todo
|
||||
<dt>Folder:</dt>
|
||||
<dd>-</dd>*}
|
||||
<dt>Operating system:</dt>
|
||||
<dd><%= os_version ? os_version.name : "<i>unknown</i>" %></dd>
|
||||
{* @todo
|
||||
<dt>BIOS string copier:</dt>
|
||||
<dd>No</dd>*}
|
||||
<dt>Virtualization state:</dt>
|
||||
<dd><%
|
||||
if (PV_drivers_up_to_date)
|
||||
%><span class="label label-success">Optimized</span><%
|
||||
else
|
||||
%><span class="label label-important">Not optimized</span><%
|
||||
%></dd>
|
||||
<dt>Uptime:</dt>
|
||||
<dd><%= start_time ? xo.formatDuration.fromNow(start_time, 'minutes') : '<i>N/A</i>' %></dd>
|
||||
<dt>Host:</dt>
|
||||
<dd><% if (host_name)
|
||||
{{
|
||||
%><a href="{$base_path}/servers/<%= host_uuid %>"><%= host_name%></a><%
|
||||
}
|
||||
else
|
||||
{{
|
||||
%><i>none</i><%
|
||||
} %></dd>
|
||||
<dt>UUID:</dt>
|
||||
<dd><%= id %></dd>
|
||||
</dl>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>OS boot parameters:</dt>
|
||||
<dd><%= HVM_boot_params.length ? HVM_boot_params.join(" ") : "<i>none</i>" %></dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="cpu">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Number of VCPUs:</dt>
|
||||
<dd><%= VCPUs_number %></dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="memory">
|
||||
{* @todo
|
||||
<div class="progress progress-big progress-danger">
|
||||
<div class="bar bar-info" style="width: 100%;">vmdb1<br/>(1024M)</div>
|
||||
</div>*}
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Used memory:</dt>
|
||||
<dd><%= used_memory || "<i>not available</i>" %></dt>
|
||||
<dt>Total memory:</dt>
|
||||
<dd>
|
||||
<%= xo.formatSize(total_memory) %>
|
||||
(min: <%= xo.formatSize(memory_dynamic_min) %>,
|
||||
max: <%= xo.formatSize(memory_dynamic_max) %>)
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="storage">
|
||||
<table class="table table-hover table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Position</th>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<th>SR</th>
|
||||
<th>Size</th>
|
||||
<th>Read only</th>
|
||||
<th>Priority</th>
|
||||
<th>Active</th>
|
||||
<th>Device path</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody><% for (var i = 0; i < VBDs.length; ++i)
|
||||
{{
|
||||
var VBD = VBDs[i];
|
||||
%><tr>
|
||||
<td><i class="icon-hdd"></i> <%= i %></td>
|
||||
<td><%= VBD.name %></td>
|
||||
<td><%= VBD.description %></td>
|
||||
<td><%= VBD.SR_name %></td>
|
||||
<td><%= xo.formatSize(VBD.size) %></td>
|
||||
<td><%= VBD.read_only ? 'Yes' : 'No' %></td>
|
||||
<td><%= VBD.priority %></td>
|
||||
<td><% if (VBD.currently_attached)
|
||||
{{
|
||||
%><span class="label label-success">Yes</span><%
|
||||
}
|
||||
else
|
||||
{{
|
||||
%><span class="label label-important">No</span><%
|
||||
} %></td>
|
||||
<td><%= VBD.path %></td>
|
||||
</tr><%
|
||||
} %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="network">
|
||||
<table class="table table-hover table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Device</th>
|
||||
<th>MAC</th>
|
||||
<th>Limit</th>
|
||||
<th>Network</th>
|
||||
<th>IP address</th>
|
||||
<th>Active</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% for (var i = 0; i < VIFs.length; ++i)
|
||||
{{
|
||||
var VIF = VIFs[i];
|
||||
%><tr>
|
||||
<td><i class="icon-sitemap"></i> <%= i %></td>
|
||||
<td class="mac-address"><%= VIF.MAC %></td>
|
||||
<td>-</td> {* @todo *}
|
||||
<td><%= VIF.network_name || '<i>unknown</i>' %></td>
|
||||
<td><%= VIF.ip %></td>
|
||||
<td><% if (VIF.currently_attached)
|
||||
{{
|
||||
%><span class="label label-success">Yes</span><%
|
||||
}
|
||||
else
|
||||
{{
|
||||
%><span class="label label-important">No</span><%
|
||||
} %></td>
|
||||
</tr><% ;
|
||||
} %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="console">
|
||||
<p>Not implemented so far</p>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="perfs">
|
||||
<p>Not implemented so far</p>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="snapshots">
|
||||
<table class="table table-hover table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Snapshot name</th>
|
||||
<th>Origin</th>
|
||||
<th>Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody><% for (var i = 0; i < snapshots.length; ++i)
|
||||
{{
|
||||
var snapshot = snapshots[i];
|
||||
var date = moment.unix(snapshot.time).format('LLLL');
|
||||
%><tr>
|
||||
<td><i class="icon-camera"></i> <%= snapshot.name %></td>
|
||||
<td><a href="{$base_path}/vms/<%= snapshot.origin_uuid %>"><%= snapshot.origin_name %></a></td>
|
||||
<td><%= date %></td>
|
||||
</tr><%
|
||||
} %></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="alerts">
|
||||
<p>Not yet implemented.</p>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="other">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Preferred host:</dt>
|
||||
<dd><%
|
||||
if (!preferred_host)
|
||||
{{
|
||||
%><i>none</i><%
|
||||
}
|
||||
else if (preferred_host.name)
|
||||
{{
|
||||
%><a href="{$base_path}/servers/<%= preferred_host.uuid %>"><%= preferred_host.name %></a><%
|
||||
}
|
||||
else
|
||||
{{
|
||||
%><i>unknown host with opaque reference <%= preferred_host.ref %></i><%
|
||||
}
|
||||
%></dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="logs">
|
||||
<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><% for (var i = 0; i < messages.length; ++i)
|
||||
{{
|
||||
var msg = messages[i];
|
||||
var date = moment.unix(msg.time).format('LLLL');
|
||||
%><tr>
|
||||
<td><i class="icon-comment"></i> <%= msg.subject %></td>
|
||||
<td><%= msg.body %></td>
|
||||
<td><%= date %></td>
|
||||
<td>00:10:16</td> {* todo *}
|
||||
</tr><%
|
||||
} %></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$('#tab a').click(function (e) {{
|
||||
e.preventDefault();
|
||||
$(this).tab('show');
|
||||
});
|
||||
</<% %>script>
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<div class="row" id="region-main"></div>
|
||||
</div>
|
||||
{/block body}
|
Loading…
Reference in New Issue
Block a user