diff --git a/xCAT-UI/css/service.css b/xCAT-UI/css/service.css
new file mode 100644
index 000000000..721460bf7
--- /dev/null
+++ b/xCAT-UI/css/service.css
@@ -0,0 +1,365 @@
+/*--- Dialogs ---*/
+.ui-dialog input {
+ border: solid 1px;
+ font: 12px verdana, arial, helvetica, sans-serif;
+}
+
+.ui-dialog label,.ui-dialog input,.ui-dialog p,.ui-dialog button,.ui-dialog td {
+ font: 12px verdana, arial, helvetica, sans-serif;
+}
+
+.ui-widget {
+ font: 12px verdana, arial, helvetica, sans-serif;
+}
+
+/*--- Tooltip ---*/
+.tooltip {
+ background-color: #000;
+ border: 1px solid #fff;
+ padding: 10px 15px;
+ display: none;
+ color: #fff;
+ text-align: left;
+ max-width: 300px;
+ font-size: 10px;
+ /* Outline radius for firefox only */
+ -moz-box-shadow: 0 0 10px #000;
+ -webkit-box-shadow: 0 0 10px #000;
+}
+
+.tooltip h3 {
+ margin: 0px;
+}
+
+/*--- Login dialog ---*/
+#logdialog {
+ font: 12px verdana, arial, helvetica, sans-serif;
+ width: 600px;
+}
+
+#logdialog table {
+ border: solid 0px;
+}
+
+#logdialog td {
+ width: 100px;
+ height: 35px;
+ color: #0078AE;
+ font-weight: bold;
+ border: solid 0px;
+}
+
+#logdialog input {
+ width: 210px;
+ border: solid 1px #0078AE;
+ font-size: 12px;
+ padding-bottom: 5px;
+}
+
+#logdialog p {
+ font-size: 18px;
+}
+
+#logdialog button {
+ font-weight: bold;
+ width: 90px;
+ float: right;
+}
+
+#loginput {
+ background-color: #f5f5f5;
+ height: 300px;
+}
+
+#loginfo {
+ margin: 5px 0px;
+ text-align: right;
+ color: #f5f5f5;
+ font-weight:bold;
+}
+
+/*--- Header ---*/
+#header {
+ height: 40px;
+ width: 1000px;
+ margin: 0px auto;
+ -moz-border-radius: .3em;
+ -webkit-border-radius: .3em;
+ border-radius: .3em;
+}
+
+/* User name and log out */
+#header div {
+ float: right;
+}
+
+#header div span {
+ color: #424242;
+ padding: 2px 15px 0px 2px; /* Top right left bottom*/
+ text-align: right;
+ text-decoration: none;
+ display: block;
+}
+
+#header div a {
+ padding: 3px 15px 0px 3px; /* Top right left bottom*/
+ text-align: right;
+ color: blue;
+ font-weight: normal;
+ text-decoration: none;
+ display: block;
+ cursor: pointer;
+}
+
+#header div a:hover {
+ color: red;
+}
+
+#layoutselector {
+ padding: 2px 10px 0px 2px; /* Top right left bottom*/
+ text-align: right;
+ color: #FFC125;
+ text-decoration: none;
+ display: block;
+}
+
+/*--- Body and content ---*/
+body {
+ background-color: #1C1C1C;
+ font: 12px verdana, arial, helvetica, sans-serif;
+}
+
+.content {
+ -moz-border-radius: .3em;
+ -webkit-border-radius: .3em;
+ border-radius: .3em;
+ width: 1000px;
+ min-height: 600px;
+ margin: 10px auto;
+ background-color: white;
+ overflow: auto;
+}
+
+#content ul.ui-widget-header {
+ border-color: #4297D7 #4297D7 #7BB642;
+ border-width: 1px 1px 4px;
+}
+
+.ui-state-highlight {
+ vertical-align: top;
+ word-wrap: break-word;
+}
+
+/*--- jQuery tabs ---*/
+.tab {
+ font: 12px verdana, arial, helvetica, sans-serif;
+ border-style: none;
+ overflow: visible;
+}
+
+.ui-icon-close {
+ float: left;
+ margin: 0.4em 0.2em 0 0;
+ cursor: pointer;
+}
+
+/*--- Inventory and user entry ---*/
+table {
+ border-width: 1px;
+ border-spacing: 0px;
+ border-style: solid;
+ border-collapse: collapse;
+}
+
+/*--- jQuery datatable ---*/
+.dataTables_wrapper {
+ overflow: auto;
+ width: auto;
+ margin: 10px auto;
+}
+
+/*** Show X entries ***/
+.dataTables_length {
+ width: 40%;
+ float: left;
+ padding: 10px 20px;
+ text-align: left;
+}
+
+/*** Search ***/
+.dataTables_filter {
+ width: 40%;
+ margin: 10px 0px;
+ display: block;
+ float: right;
+ text-align: right;
+}
+
+.tab input,select {
+ font: 12px verdana, arial, helvetica, sans-serif;
+ border: solid 1px;
+ padding: 4px;
+}
+
+.sorting,.sorting_asc,.sorting_desc {
+ background: none;
+}
+
+/*** Showing X to X of X entries ***/
+.dataTables_info {
+ padding: 10px 20px;
+ width: 40%;
+ float: left;
+}
+
+/*** < > buttons ***/
+.paginate_disabled_previous,.paginate_enabled_previous,.paginate_disabled_next,.paginate_enabled_next
+ {
+ height: 19px;
+ width: 19px;
+ margin-left: 2px;
+ float: left;
+}
+
+/*** Table ***/
+.datatable {
+ width: 100%;
+ border-width: 1px;
+ border-spacing: 0px;
+ border-style: solid;
+ border-collapse: collapse;
+ display: inline-table;
+}
+
+/*** Row color (odd) ***/
+.datatable tr.odd {
+ background-color: white;
+}
+
+.datatable tr.odd td.sorting_1 {
+ background-color: white;
+}
+
+/*** Row color (even) ***/
+.datatable tr.even {
+ background-color: white;
+}
+
+.datatable tr.even td.sorting_1 {
+ background-color: white;
+}
+
+.datatable a {
+ text-decoration: none;
+ color: blue;
+ cursor: pointer;
+}
+
+.datatable a:hover {
+ color: red;
+}
+
+/*--- Superfish menu ---*/
+.sf-menu {
+ background : none repeat scroll 0 0 #2191C0;
+ border :1px solid #f5f5f5;
+ border-radius: 0.3em 0.3em 0.3em 0.3em;
+}
+
+.sf-menu a {
+ color: white;
+ padding: 10px 25px;
+ font-weight: bold;
+}
+
+.sf-sub-indicator{
+ right:0;
+}
+
+.sf-shadow ul {
+ padding: 0px;
+}
+
+.sf-menu li:hover, .sf-menu li.sfHover {
+ background: #79C9EC;
+}
+
+/*--- Generic tags ---*/
+p {
+ word-wrap: break-word;
+}
+
+a {
+ cursor: pointer;
+ color: blue;
+}
+
+th {
+ font: bold 12px verdana, arial, helvetica, sans-serif;
+ border-width: 1px;
+ padding: 8px 0px;
+ min-width: 50px;
+ border-style: solid;
+ vertical-align: middle;
+ text-align: center;
+}
+
+td {
+ font: 12px verdana, arial, helvetica, sans-serif;
+ color: #424242;
+ padding: 8px 0px;
+ border-width: 1px;
+ border-style: solid;
+ vertical-align: middle;
+ text-align: center;
+}
+
+fieldset {
+ margin-bottom: 5px;
+ border-width: 1px 0 0 0;
+ border-style: solid none none none;
+}
+
+label {
+ color: #424242;
+ display: inline-block;
+ line-height: 1.5;
+ vertical-align: top;
+ width: 140px;
+}
+
+legend {
+ font: 12px verdana, arial, helvetica, sans-serif;
+ color: #424242;
+ font-weight: bold;
+ padding: 10px 15px;
+}
+
+ol {
+ margin: 0;
+ padding: 0;
+}
+
+li {
+ list-style: none;
+ padding: 5px 5px 5px 20px;
+ margin: 0;
+}
+
+input,textarea,select {
+ font: 12px verdana, arial, helvetica, sans-serif;
+ border: solid 1px;
+ padding: 5px;
+ display: inline-table;
+}
+
+table a {
+ font: 12px verdana, arial, helvetica, sans-serif;
+ text-decoration: none;
+ color: blue;
+ cursor: pointer;
+}
+
+table a:hover {
+ color: red;
+}
\ No newline at end of file
diff --git a/xCAT-UI/css/style.css b/xCAT-UI/css/style.css
index 95552110f..611ebb816 100644
--- a/xCAT-UI/css/style.css
+++ b/xCAT-UI/css/style.css
@@ -31,43 +31,50 @@
margin: 0px;
}
-/*--------------- login dialog ---------*/
+/*--- Login dialog ---*/
#logdialog {
+ font: 12px verdana, arial, helvetica, sans-serif;
width: 600px;
}
-#logdialog td{
- width: 110px;
- height: 30px;
+#logdialog table {
+ border: solid 0px;
+ margin: 0px auto;
+}
+
+#logdialog td {
+ width: 100px;
+ height: 35px;
color: #0078AE;
- font-size: 14px;
font-weight: bold;
- border-width: 0px;
+ border: solid 0px;
}
-#logdialog input{
- width: 219px;
+#logdialog input {
+ width: 210px;
border: solid 1px #0078AE;
- font-size: 14px;
+ font-size: 12px;
+ padding-bottom: 5px;
}
-#logdialog p{
-
+#logdialog p {
font-size: 18px;
}
-#logdialog button{
+#logdialog button {
font-weight: bold;
width: 90px;
+ float: right;
}
#loginput {
background-color: #f5f5f5;
- height: 260px;
+ height: 280px;
}
-#loginfo{
- text-align:right;
+#loginfo {
+ margin: 5px 0px;
+ text-align: right;
color: #f5f5f5;
font-weight:bold;
}
@@ -77,7 +84,7 @@
height: 39px;
width: 1000px;
margin: 0px auto;
- background: url(../images/header-gloss-wave.png) 50% 50% repeat-x;
+ background: url(../images/jquery/default/ui-bg_highlight-soft_75_2191c0_1x100.png) 50% 50% repeat-x;
-moz-border-radius: .5em;
-webkit-border-radius: .5em;
border-radius: .5em;
@@ -149,7 +156,7 @@
/*--------------- Body and content ---------------*/
body {
- background-color: #1C1C1C;
+ background: #1C1C1C;
font: 12px verdana, arial, helvetica, sans-serif;
}
diff --git a/xCAT-UI/js/custom/hmc.js b/xCAT-UI/js/custom/hmc.js
index ad5afbd3c..c96aefc95 100644
--- a/xCAT-UI/js/custom/hmc.js
+++ b/xCAT-UI/js/custom/hmc.js
@@ -122,7 +122,7 @@ hmcPlugin.prototype.loadProvisionPage = function(tabId) {
var provForm = $('
');
// Create info bar
- var infoBar = createInfoBar('Provision a node on system P server.');
+ var infoBar = createInfoBar('Provision a node on System p.');
provForm.append(infoBar);
// Append to provision tab
@@ -369,7 +369,7 @@ function addHmcNode(){
}
/**
- * Add system p node, contains frame, cec, lpar
+ * Add System p node, contains frame, cec, lpar
*
* @return Nothing
*/
diff --git a/xCAT-UI/js/service/service.js b/xCAT-UI/js/service/service.js
new file mode 100644
index 000000000..8faffbe40
--- /dev/null
+++ b/xCAT-UI/js/service/service.js
@@ -0,0 +1,2350 @@
+/**
+ * Global variables
+ */
+var serviceTabs;
+var nodeName;
+var nodePath;
+var nodeStatus;
+var gangliaTimer;
+
+/**
+ * Initialize service page
+ */
+function initServicePage() {
+ // Reuqired JQuery plugins
+ includeJs("js/jquery/jquery.dataTables.min.js");
+ includeJs("js/jquery/jquery.cookie.min.js");
+ includeJs("js/jquery/tooltip.min.js");
+ includeJs("js/jquery/superfish.min.js");
+ includeJs("js/jquery/jquery.jqplot.min.js");
+ includeJs("js/jquery/jqplot.dateAxisRenderer.min.js");
+
+ // Show service page
+ $("#content").children().remove();
+ includeJs("js/service/service.js");
+ includeJs("js/service/utils.js");
+ loadServicePage();
+}
+
+/**
+ * Load service page
+ */
+function loadServicePage() {
+ // If the page is loaded
+ if ($('#content').children().length) {
+ // Do not load again
+ return;
+ }
+
+ // Create manage and provision tabs
+ serviceTabs = new Tab();
+ serviceTabs.init();
+ $('#content').append(serviceTabs.object());
+
+ var manageTabId = 'manageTab';
+ serviceTabs.add(manageTabId, 'Manage', '', false);
+ loadManagePage(manageTabId);
+
+ var provTabId = 'provisionTab';
+ serviceTabs.add(provTabId, 'Provision', '', false);
+ loadzProvisionPage(provTabId);
+
+ serviceTabs.select(manageTabId);
+
+ // Get zVM host names
+ if (!$.cookie('srv_zvm')){
+ $.ajax( {
+ url : 'lib/srv_cmd.php',
+ dataType : 'json',
+ data : {
+ cmd : 'webportal',
+ tgt : '',
+ args : 'lszvm',
+ msg : ''
+ },
+
+ success : function(data) {
+ setzVMCookies(data);
+ loadzVMs();
+ }
+ });
+ } else {
+ loadzVMs();
+ }
+
+ // Get OS image names
+ if (!$.cookie('srv_imagenames')){
+ $.ajax( {
+ url : 'lib/srv_cmd.php',
+ dataType : 'json',
+ data : {
+ cmd : 'tabdump',
+ tgt : '',
+ args : 'osimage',
+ msg : ''
+ },
+
+ success : function(data) {
+ setOSImageCookies(data);
+ loadOSImages();
+ }
+ });
+ } else {
+ loadOSImages();
+ }
+
+ // Get contents of hosts table
+ if (!$.cookie('srv_groups')) {
+ $.ajax( {
+ url : 'lib/srv_cmd.php',
+ dataType : 'json',
+ data : {
+ cmd : 'tabdump',
+ tgt : '',
+ args : 'hosts',
+ msg : ''
+ },
+
+ success : function(data) {
+ setGroupCookies(data);
+ loadGroups();
+ }
+ });
+ } else {
+ loadGroups();
+ }
+
+ // Get nodes owned by user
+ $.ajax( {
+ url : 'lib/srv_cmd.php',
+ dataType : 'json',
+ data : {
+ cmd : 'tabdump',
+ tgt : '',
+ args : 'nodetype',
+ msg : ''
+ },
+
+ success : function(data) {
+ setUserNodes(data);
+ getUserNodesDef();
+ getNodesCurrentLoad();
+ }
+ });
+
+
+}
+
+/**
+ * Load manage page
+ *
+ * @param tabId
+ * Tab ID where page will reside
+ * @return Nothing
+ */
+function loadManagePage(tabId) {
+ // Create manage form
+ var loader = createLoader('');
+ var manageForm = $('').append(loader);
+
+ // Append to manage tab
+ $('#' + tabId).append(manageForm);
+}
+
+/**
+ * Get the user nodes definitions
+ */
+function getUserNodesDef() {
+ var userName = $.cookie('srv_usrname');
+ var userNodes = $.cookie(userName + '_usrnodes');
+ if (userNodes) {
+ // Get nodes definitions
+ $.ajax( {
+ url : 'lib/srv_cmd.php',
+ dataType : 'json',
+ data : {
+ cmd : 'lsdef',
+ tgt : '',
+ args : userNodes,
+ msg : ''
+ },
+
+ success : loadNodesTable
+ });
+ } else {
+ prompt('Warning', $('Your session has expired! Please log out and back in.
'));
+ }
+}
+
+/**
+ * Load user nodes definitions into a table
+ *
+ * @param data
+ * Data from HTTP request
+ * @return Nothing
+ */
+function loadNodesTable(data) {
+ // Clear the tab before inserting the table
+ $('#manageTab').children().remove();
+
+ // Nodes datatable ID
+ var nodesDTId = 'userNodesDT';
+
+ // Hash of node attributes
+ var attrs = new Object();
+ // Node attributes
+ var headers = new Object();
+ var node, args;
+ // Create hash of node attributes
+ for (var i in data.rsp) {
+ // Get node name
+ if (data.rsp[i].indexOf('Object name:') > -1) {
+ var temp = data.rsp[i].split(': ');
+ node = jQuery.trim(temp[1]);
+
+ // Create a hash for the node attributes
+ attrs[node] = new Object();
+ i++;
+ }
+
+ // Get key and value
+ args = data.rsp[i].split('=', 2);
+ var key = jQuery.trim(args[0]);
+ var val = jQuery.trim(data.rsp[i].substring(data.rsp[i].indexOf('=') + 1, data.rsp[i].length));
+
+ // Create a hash table
+ attrs[node][key] = val;
+ headers[key] = 1;
+ }
+
+ // Sort headers
+ var sorted = new Array();
+ var attrs2hide = new Array('status', 'statustime', 'appstatus', 'appstatustime', 'usercomment');
+ var attrs2show = new Array('arch', 'groups', 'hcp', 'hostnames', 'ip', 'os', 'userid');
+ for (var key in headers) {
+ // Show node attributes
+ if (jQuery.inArray(key, attrs2show) > -1) {
+ sorted.push(key);
+ }
+ }
+ sorted.sort();
+
+ // Add column for check box, node, ping, power, monitor, and comments
+ sorted.unshift('',
+ 'node',
+ 'status',
+ 'power',
+ 'monitor',
+ 'comments');
+
+ // Create a datatable
+ var nodesDT = new DataTable(nodesDTId);
+ nodesDT.init(sorted);
+
+ // Go through each node
+ for (var node in attrs) {
+ // Create a row
+ var row = new Array();
+
+ // Create a check box, node link, and get node status
+ var checkBx = $('');
+ var nodeLink = $('' + node + '').bind('click', loadNode);
+
+ // If there is no status attribute for the node, do not try to access hash table
+ // Else the code will break
+ var status = '';
+ if (attrs[node]['status']) {
+ status = attrs[node]['status'].replace('sshd', 'ping');
+ }
+
+ // Push in checkbox, node, status, monitor, and power
+ row.push(checkBx, nodeLink, status, '', '');
+
+ // If the node attributes are known (i.e the group is known)
+ if (attrs[node]['groups']) {
+ // Put in comments
+ var comments = attrs[node]['usercomment'];
+ // If no comments exists, show 'No comments' and set icon image source
+ var iconSrc;
+ if (!comments) {
+ comments = 'No comments';
+ iconSrc = 'images/nodes/ui-icon-no-comment.png';
+ } else {
+ iconSrc = 'images/nodes/ui-icon-comment.png';
+ }
+
+ // Create comments icon
+ var tipID = node + 'Tip';
+ var icon = $('').css({
+ 'width': '18px',
+ 'height': '18px'
+ });
+
+ // Create tooltip
+ var tip = createCommentsToolTip(comments);
+ var col = $('').append(icon);
+ col.append(tip);
+ row.push(col);
+
+ // Generate tooltips
+ icon.tooltip({
+ position: "center right",
+ offset: [-2, 10],
+ effect: "fade",
+ opacity: 0.8,
+ relative: true,
+ delay: 500
+ });
+ } else {
+ // Do not put in comments if attributes are not known
+ row.push('');
+ }
+
+ // Go through each header
+ for (var i = 6; i < sorted.length; i++) {
+ // Add the node attributes to the row
+ var key = sorted[i];
+
+ // Do not put comments and status in twice
+ if (key != 'usercomment' && key != 'status' && key.indexOf('statustime') < 0) {
+ var val = attrs[node][key];
+ if (val) {
+ row.push($('' + val + ''));
+ } else {
+ row.push('');
+ }
+ }
+ }
+
+ // Add the row to the table
+ nodesDT.add(row);
+ }
+
+ // Create info bar
+ var infoBar = createInfoBar('Manage and monitor your Linux virtual machines on System z.');
+ $('#manageTab').append(infoBar);
+
+ // Insert action bar and nodes datatable
+ $('#manageTab').append(nodesDT.object());
+
+ // Turn table into a datatable
+ $('#' + nodesDTId).dataTable({
+ 'iDisplayLength': 50,
+ 'bLengthChange': false,
+ "sScrollX": "100%",
+ "sScrollXInner": "110%"
+ });
+
+ // Set datatable header class to add color
+ $('.datatable thead').attr('class', 'ui-widget-header');
+
+ // Do not sort ping, power, and comment column
+ var cols = $('#' + nodesDTId + ' thead tr th').click(function() {
+ getNodeAttrs(group);
+ });
+ var checkboxCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(0)');
+ var pingCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(2)');
+ var powerCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(3)');
+ var monitorCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(4)');
+ var commentCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(5)');
+ checkboxCol.unbind('click');
+ pingCol.unbind('click');
+ powerCol.unbind('click');
+ monitorCol.unbind('click');
+ commentCol.unbind('click');
+
+ // Refresh the node ping, power, and monitor status on-click
+ var nodes = getNodesShown(nodesDTId);
+ pingCol.find('span a').click(function() {
+ refreshNodeStatus(nodes);
+ });
+ powerCol.find('span a').click(function() {
+ refreshPowerStatus(nodes);
+ });
+ monitorCol.find('span a').click(function() {
+ refreshGangliaStatus(nodes);
+ });
+
+ // Create actions menu
+ // Power on
+ var powerOnLnk = $('Power on');
+ powerOnLnk.click(function() {
+ var tgtNodes = getNodesChecked(nodesDTId);
+ if (tgtNodes) {
+ powerNode(tgtNodes, 'on');
+ }
+ });
+
+ // Power off
+ var powerOffLnk = $('Power off');
+ powerOffLnk.click(function() {
+ var tgtNodes = getNodesChecked(nodesDTId);
+ if (tgtNodes) {
+ powerNode(tgtNodes, 'off');
+ }
+ });
+
+ // Turn monitoring on
+ var monitorOnLnk = $('Monitor on');
+ monitorOnLnk.click(function() {
+ var tgtNodes = getNodesChecked(nodesDTId);
+ if (tgtNodes) {
+ monitorNode(tgtNodes, 'on');
+ }
+ });
+
+ // Turn monitoring off
+ var monitorOffLnk = $('Monitor off');
+ monitorOffLnk.click(function() {
+ var tgtNodes = getNodesChecked(nodesDTId);
+ if (tgtNodes) {
+ monitorNode(tgtNodes, 'off');
+ }
+ });
+
+ // Delete
+ var deleteLnk = $('Delete');
+ deleteLnk.click(function() {
+ var tgtNodes = getNodesChecked(nodesDTId);
+ if (tgtNodes) {
+ deleteNode(tgtNodes);
+ }
+ });
+
+ // Unlock
+ var unlockLnk = $('Unlock');
+ unlockLnk.click(function() {
+ var tgtNodes = getNodesChecked(nodesDTId);
+ if (tgtNodes) {
+ unlockNode(tgtNodes);
+ }
+ });
+
+ // Prepend menu to datatable
+ var actionsLnk = 'Actions';
+ var actionMenu = createMenu([deleteLnk, powerOnLnk, powerOffLnk, monitorOnLnk, monitorOffLnk, unlockLnk]);
+ var menu = createMenu([[actionsLnk, actionMenu]]);
+ menu.superfish();
+ $('#' + nodesDTId + '_filter').css('display', 'inline-block');
+ $('#' + nodesDTId + '_wrapper').prepend(menu);
+
+ $('.sf-menu li:hover, .sf-menu li.sfHover').attr('class', 'ui-widget-header');
+
+ // Get power and monitor status
+ var nodes = getNodesShown(nodesDTId);
+ refreshPowerStatus(nodes);
+ refreshGangliaStatus(nodes);
+}
+
+/**
+ * Refresh ping status for each node
+ *
+ * @param nodes
+ * Nodes to get ping status
+ * @return Nothing
+ */
+function refreshNodeStatus(nodes) {
+ // Show ping loader
+ var nodesDTId = 'userNodesDT';
+ var pingCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(2)');
+ pingCol.find('img').show();
+
+ // Get the node ping status
+ $.ajax( {
+ url : 'lib/srv_cmd.php',
+ dataType : 'json',
+ data : {
+ cmd : 'nodestat',
+ tgt : nodes,
+ args : '-u',
+ msg : ''
+ },
+
+ success : loadNodePing
+ });
+}
+
+/**
+ * Load node ping status for each node
+ *
+ * @param data
+ * Data returned from HTTP request
+ * @return Nothing
+ */
+function loadNodePing(data) {
+ var nodesDTId = 'userNodesDT';
+ var datatable = $('#' + nodesDTId).dataTable();
+ var rsp = data.rsp;
+ var args, rowPos, node, status;
+
+ // Get all nodes within datatable
+ for (var i in rsp) {
+ args = rsp[i].split(':');
+
+ // args[0] = node and args[1] = status
+ node = jQuery.trim(args[0]);
+ status = jQuery.trim(args[1]).replace('sshd', 'ping');
+
+ // Get row containing node
+ rowPos = findRow(node, '#' + nodesDTId, 1);
+
+ // Update ping status column
+ datatable.fnUpdate(status, rowPos, 2, false);
+ }
+
+ // Hide status loader
+ var pingCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(2)');
+ pingCol.find('img').hide();
+ datatable.fnDraw();
+}
+
+/**
+ * Refresh power status for each node
+ *
+ * @param nodes
+ * Nodes to get power status
+ * @return Nothing
+ */
+function refreshPowerStatus(nodes) {
+ // Show power loader
+ var nodesDTId = 'userNodesDT';
+ var powerCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(3)');
+ powerCol.find('img').show();
+
+ // Get power status
+ $.ajax( {
+ url : 'lib/srv_cmd.php',
+ dataType : 'json',
+ data : {
+ cmd : 'rpower',
+ tgt : nodes,
+ args : 'stat',
+ msg : ''
+ },
+
+ success : loadPowerStatus
+ });
+}
+
+/**
+ * Load power status for each node
+ *
+ * @param data
+ * Data returned from HTTP request
+ * @return Nothing
+ */
+function loadPowerStatus(data) {
+ var nodesDTId = 'userNodesDT';
+ var datatable = $('#' + nodesDTId).dataTable();
+ var power = data.rsp;
+ var rowPos, node, status, args;
+
+ for (var i in power) {
+ // power[0] = nodeName and power[1] = state
+ args = power[i].split(':');
+ node = jQuery.trim(args[0]);
+ status = jQuery.trim(args[1]);
+
+ // Get the row containing the node
+ rowPos = findRow(node, '#' + nodesDTId, 1);
+
+ // Update the power status column
+ datatable.fnUpdate(status, rowPos, 3, false);
+ }
+
+ // Hide power loader
+ var powerCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(3)');
+ powerCol.find('img').hide();
+ datatable.fnDraw();
+}
+
+/**
+ * Refresh the status of Ganglia for each node
+ *
+ * @param nodes
+ * Nodes to get Ganglia status
+ * @return Nothing
+ */
+function refreshGangliaStatus(nodes) {
+ // Show ganglia loader
+ var nodesDTId = 'userNodesDT';
+ var gangliaCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(4)');
+ gangliaCol.find('img').show();
+
+ // Get the status of Ganglia
+ $.ajax( {
+ url : 'lib/srv_cmd.php',
+ dataType : 'json',
+ data : {
+ cmd : 'webrun',
+ tgt : '',
+ args : 'gangliastatus;' + nodes,
+ msg : ''
+ },
+
+ success : loadGangliaStatus
+ });
+}
+
+/**
+ * Load the status of Ganglia for a given group
+ *
+ * @param data
+ * Data returned from HTTP request
+ * @return Nothing
+ */
+function loadGangliaStatus(data) {
+ // Get datatable
+ var nodesDTId = 'userNodesDT';
+ var datatable = $('#' + nodesDTId).dataTable();
+ var ganglia = data.rsp;
+ var rowNum, node, status;
+
+ for ( var i in ganglia) {
+ // ganglia[0] = nodeName and ganglia[1] = state
+ node = jQuery.trim(ganglia[i][0]);
+ status = jQuery.trim(ganglia[i][1]);
+
+ // Get the row containing the node
+ rowNum = findRow(node, '#' + nodesDTId, 1);
+
+ // Update the power status column
+ datatable.fnUpdate(status, rowNum, 4);
+ }
+
+ // Hide Ganglia loader
+ var gangliaCol = $('#' + nodesDTId + '_wrapper .dataTables_scrollHead .datatable thead tr th:eq(4)');
+ gangliaCol.find('img').hide();
+ datatable.fnDraw();
+}
+
+/**
+ * Load inventory for given node
+ *
+ * @param e
+ * Windows event
+ * @return Nothing
+ */
+function loadNode(e) {
+ if (!e) {
+ e = window.event;
+ }
+
+ // Get node that was clicked
+ var node = (e.target) ? e.target.id : e.srcElement.id;
+
+ // Create a new tab to show inventory
+ var tabId = node + '_inventory';
+
+ if(!$('#' + tabId).length) {
+ // Add new tab, only if one does not exist
+ var loader = createLoader(node + 'Loader');
+ loader = $('').append(loader);
+ serviceTabs.add(tabId, node, loader, true);
+
+ // Get node inventory
+ var msg = 'out=' + tabId + ',node=' + node;
+ $.ajax( {
+ url : 'lib/srv_cmd.php',
+ dataType : 'json',
+ data : {
+ cmd : 'rinv',
+ tgt : node,
+ args : 'all',
+ msg : msg
+ },
+
+ success : showInventory
+ });
+ }
+
+ // Select new tab
+ serviceTabs.select(tabId);
+}
+
+/**
+ * Show node inventory
+ *
+ * @param data
+ * Data from HTTP request
+ * @return Nothing
+ */
+function showInventory(data) {
+ var args = data.msg.split(',');
+
+ // Get tab ID
+ var tabId = args[0].replace('out=', '');
+ // Get node
+ var node = args[1].replace('node=', '');
+ // Get node inventory
+ var inv = data.rsp[0].split(node + ':');
+
+ // Remove loader
+ $('#' + tabId).find('img').remove();
+
+ // Create array of property keys
+ var keys = new Array('userId', 'host', 'os', 'arch', 'hcp', 'priv', 'memory', 'proc', 'disk', 'nic');
+
+ // Create hash table for property names
+ var attrNames = new Object();
+ attrNames['userId'] = 'z/VM UserID:';
+ attrNames['host'] = 'z/VM Host:';
+ attrNames['os'] = 'Operating System:';
+ attrNames['arch'] = 'Architecture:';
+ attrNames['hcp'] = 'HCP:';
+ attrNames['priv'] = 'Privileges:';
+ attrNames['memory'] = 'Total Memory:';
+ attrNames['proc'] = 'Processors:';
+ attrNames['disk'] = 'Disks:';
+ attrNames['nic'] = 'NICs:';
+
+ // Create hash table for node attributes
+ var attrs = getAttrs(keys, attrNames, inv);
+
+ // Create division to hold inventory
+ var invDivId = node + 'Inventory';
+ var invDiv = $('');
+
+ var infoBar = createInfoBar('Below is the inventory for the virtual machine you selected.');
+ invDiv.append(infoBar);
+
+ /**
+ * General info section
+ */
+ var fieldSet = $('');
+ var legend = $('');
+ fieldSet.append(legend);
+ var oList = $('
');
+ var item, label, args;
+
+ // Loop through each property
+ for ( var k = 0; k < 5; k++) {
+ // Create a list item for each property
+ item = $('');
+
+ // Create a label - Property name
+ label = $('');
+ item.append(label);
+
+ for ( var l = 0; l < attrs[keys[k]].length; l++) {
+ // Create a input - Property value(s)
+ // Handle each property uniquely
+ item.append(attrs[keys[k]][l]);
+ }
+
+ oList.append(item);
+ }
+ // Append to inventory form
+ fieldSet.append(oList);
+ invDiv.append(fieldSet);
+
+ /**
+ * Monitoring section
+ */
+ fieldSet = $('');
+ legend = $('');
+ fieldSet.append(legend);
+ getMonitorMetrics(node);
+
+ // Append to inventory form
+ invDiv.append(fieldSet);
+
+ /**
+ * Hardware info section
+ */
+ var hwList, hwItem;
+ fieldSet = $('');
+ legend = $('