diff --git a/src/sunstone/public/app/tabs/vms-tab.js b/src/sunstone/public/app/tabs/vms-tab.js
index f218b90ba0..a39cb88654 100644
--- a/src/sunstone/public/app/tabs/vms-tab.js
+++ b/src/sunstone/public/app/tabs/vms-tab.js
@@ -22,6 +22,7 @@ define(function(require) {
require('./vms-tab/panels/storage'),
require('./vms-tab/panels/network'),
require('./vms-tab/panels/snapshots'),
+ require('./vms-tab/panels/placement'),
// require('./vms-tab/panels/template')
];
diff --git a/src/sunstone/public/app/tabs/vms-tab/panels/placement.js b/src/sunstone/public/app/tabs/vms-tab/panels/placement.js
new file mode 100644
index 0000000000..41ac672a53
--- /dev/null
+++ b/src/sunstone/public/app/tabs/vms-tab/panels/placement.js
@@ -0,0 +1,182 @@
+define(function(require) {
+ /*
+ DEPENDENCIES
+ */
+
+ var Locale = require('utils/locale');
+ var Humanize = require('utils/humanize');
+ var OpenNebulaVM = require('opennebula/vm');
+
+ /*
+ CONSTANTS
+ */
+
+ var TAB_ID = require('../tabId');
+ var PANEL_ID = require('./placement/panelId');
+ var RESOURCE = "VM";
+ var XML_ROOT = "VM";
+
+ /*
+ CONSTRUCTOR
+ */
+
+ function Panel(info) {
+ this.panelId = PANEL_ID;
+ this.title = Locale.tr("Placement");
+ this.icon = "fa-sitemap";
+
+ this.element = info[XML_ROOT];
+
+ return this;
+ };
+
+ Panel.PANEL_ID = PANEL_ID;
+ Panel.prototype.html = _html;
+ Panel.prototype.setup = _setup;
+
+ return Panel;
+
+ /*
+ FUNCTION DEFINITIONS
+ */
+
+ function _html() {
+ var that = this;
+ var html = '
\
+
\
+ \
+ \
+ ' + Locale.tr("#") + ' | \
+ ' + Locale.tr("Host") + ' | \
+ ' + Locale.tr("Datastore") + ' | \
+ ' + Locale.tr("Action") + ' | \
+ ' + Locale.tr("Reason") + ' | \
+ ' + Locale.tr("Chg time") + ' | \
+ ' + Locale.tr("Total time") + ' | \
+ ' + Locale.tr("Prolog time") + ' | \
+
\
+ \
+ ' ;
+
+ var history = [];
+ if (that.element.HISTORY_RECORDS.HISTORY) {
+ if ($.isArray(that.element.HISTORY_RECORDS.HISTORY))
+ history = that.element.HISTORY_RECORDS.HISTORY;
+ else if (that.element.HISTORY_RECORDS.HISTORY.SEQ)
+ history = [that.element.HISTORY_RECORDS.HISTORY];
+ } else {
+ html += ' \
+ ' + Locale.tr("No data available in table") + ' | \
+
'
+ }
+
+ var now = Math.round(new Date().getTime() / 1000);
+
+ for (var i = 0; i < history.length; i++) {
+ // :TIME time calculations copied from onevm_helper.rb
+ var stime = parseInt(history[i].STIME, 10);
+
+ var etime = parseInt(history[i].ETIME, 10)
+ etime = etime == 0 ? now : etime;
+
+ var dtime = etime - stime;
+ // end :TIME
+
+ //:PTIME
+ var stime2 = parseInt(history[i].PSTIME, 10);
+ var etime2;
+ var ptime2 = parseInt(history[i].PETIME, 10);
+ if (stime2 == 0)
+ etime2 = 0;
+ else
+ etime2 = ptime2 == 0 ? now : ptime2;
+ var dtime2 = etime2 - stime2;
+
+ //end :PTIME
+
+ html += ' \
+ ' + history[i].SEQ + ' | \
+ ' + history[i].HOSTNAME + ' | \
+ ' + history[i].DS_ID + ' | \
+ ' + OpenNebulaVM.migrateActionStr(parseInt(history[i].ACTION, 10)) + ' | \
+ ' + OpenNebulaVM.migrateReasonStr(parseInt(history[i].REASON, 10)) + ' | \
+ ' + Humanize.prettyTime(history[i].STIME) + ' | \
+ ' + Humanize.prettyDuration(dtime) + ' | \
+ ' + Humanize.prettyDuration(dtime2) + ' | \
+ | \
+
'
+ };
+ html += '\
+
\
+
\
+
' ;
+
+ if (that.element.USER_TEMPLATE.SCHED_MESSAGE) {
+ html += '\
+
\
+
\
+ \
+ \
+ ' + Locale.tr("Sched Message") + ' | \
+
\
+ \
+ \
+ \
+ ' + that.element.USER_TEMPLATE.SCHED_MESSAGE + ' | \
+
\
+ \
+
\
+
\
+
' ;
+ }
+
+ var requirements_str = that.element.USER_TEMPLATE.SCHED_REQUIREMENTS ? that.element.USER_TEMPLATE.SCHED_REQUIREMENTS : "-";
+ var rank_str = that.element.USER_TEMPLATE.SCHED_RANK ? that.element.USER_TEMPLATE.SCHED_RANK : "-";
+ var ds_requirements_str = that.element.USER_TEMPLATE.SCHED_DS_REQUIREMENTS ? that.element.USER_TEMPLATE.SCHED_DS_REQUIREMENTS : "-";
+ var ds_rank_str = that.element.USER_TEMPLATE.SCHED_DS_RANK ? that.element.USER_TEMPLATE.SCHED_DS_RANK : "-";
+
+ html += '\
+
\
+
\
+ \
+ \
+ ' + Locale.tr("Placement - Host") + ' | \
+
\
+ \
+ \
+ \
+ ' + Locale.tr("Requirements") + ' | \
+ ' + requirements_str + ' | \
+
\
+ \
+ ' + Locale.tr("Rank") + ' | \
+ ' + rank_str + ' | \
+
\
+ \
+
\
+
\
+ \
+ \
+ ' + Locale.tr("Placement - Datastore") + ' | \
+
\
+ \
+ \
+ \
+ ' + Locale.tr("DS Requirements") + ' | \
+ ' + ds_requirements_str + ' | \
+
\
+ \
+ ' + Locale.tr("DS Rank") + ' | \
+ ' + ds_rank_str + ' | \
+
\
+ \
+
\
+
\
+
' ;
+
+ return html;
+ }
+
+ function _setup(context) {
+ }
+});
diff --git a/src/sunstone/public/app/tabs/vms-tab/panels/placement/panelId.js b/src/sunstone/public/app/tabs/vms-tab/panels/placement/panelId.js
new file mode 100644
index 0000000000..feb773fc47
--- /dev/null
+++ b/src/sunstone/public/app/tabs/vms-tab/panels/placement/panelId.js
@@ -0,0 +1,3 @@
+define(function(require) {
+ return 'vm_placement_tab';
+});