AMBARI-5575. Unit tests for steps 9 (with refactor). (onechiporenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/b96edcf9 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/b96edcf9 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/b96edcf9 Branch: refs/heads/trunk Commit: b96edcf90d7d2e609aa5e2e4eb9024c8c467c000 Parents: 739d35e Author: Oleg Nechiporenko <[email protected]> Authored: Fri Apr 25 19:28:30 2014 +0300 Committer: Oleg Nechiporenko <[email protected]> Committed: Fri Apr 25 19:28:30 2014 +0300 ---------------------------------------------------------------------- ambari-web/app/assets/test/tests.js | 1 + .../app/controllers/wizard/step9_controller.js | 123 +-- ambari-web/app/templates/wizard/step9.hbs | 71 +- .../wizard/step9/step9HostTasksLogPopup.hbs | 90 ++ .../wizard/step9/step9_install_host_popup.hbs | 40 + .../templates/wizard/step9HostTasksLogPopup.hbs | 90 -- .../wizard/step9_install_host_popup.hbs | 40 - ambari-web/app/views.js | 1 + .../views/wizard/step9/hostLogPopupBody_view.js | 264 ++++++ ambari-web/app/views/wizard/step9_view.js | 389 ++++----- ambari-web/test/installer/step9_test.js | 852 ++++++++++++++++++- .../wizard/step9/hostLogPopupBody_view_test.js | 145 ++++ ambari-web/test/views/wizard/step9_view_test.js | 387 ++++++++- 13 files changed, 1997 insertions(+), 496 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/b96edcf9/ambari-web/app/assets/test/tests.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/test/tests.js b/ambari-web/app/assets/test/tests.js index 6175b3f..1ba5922 100644 --- a/ambari-web/app/assets/test/tests.js +++ b/ambari-web/app/assets/test/tests.js @@ -140,6 +140,7 @@ require('test/views/wizard/step3_view_test'); require('test/views/wizard/step5_view_test'); require('test/views/wizard/step6_view_test'); require('test/views/wizard/step9_view_test'); +require('test/views/wizard/step9/hostLogPopupBody_view_test'); require('test/views/wizard/step10_view_test'); require('test/models/host_test'); require('test/models/host_component_test'); http://git-wip-us.apache.org/repos/asf/ambari/blob/b96edcf9/ambari-web/app/controllers/wizard/step9_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step9_controller.js b/ambari-web/app/controllers/wizard/step9_controller.js index 56f97d1..8494a87 100644 --- a/ambari-web/app/controllers/wizard/step9_controller.js +++ b/ambari-web/app/controllers/wizard/step9_controller.js @@ -36,17 +36,16 @@ App.WizardStep9Controller = Em.Controller.extend({ * </code> * @type {Array.<{name: string, status: string, logTasks: object[], message: string, progress: number, isNoTasksForInstall: bool}>} */ - hosts: [], /** - * overall progress of <Install,Start and Test> page shown as progress bar on the top of the page + * Overall progress of <Install,Start and Test> page shown as progress bar on the top of the page * @type {string} */ progress: '0', /* - * json file for the mock data to be used in mock mode + * Json file for the mock data to be used in mock mode * @type {string} */ mockDataPrefix: '/data/wizard/deploy/5_hosts', @@ -119,10 +118,12 @@ App.WizardStep9Controller = Em.Controller.extend({ togglePreviousSteps: function () { if (App.testMode) { return; - } else if ('INSTALL FAILED' === this.get('content.cluster.status') && this.get('content.controllerName') == 'installerController') { - App.router.get('installerController').setStepsEnable(); + } + var installerController = App.router.get('installerController'); + if ('INSTALL FAILED' === this.get('content.cluster.status') && this.get('content.controllerName') == 'installerController') { + installerController.setStepsEnable(); } else { - App.router.get('installerController').setLowerStepsDisable(9); + installerController.setLowerStepsDisable(9); } }.observes('content.cluster.status', 'content.controllerName'), @@ -142,7 +143,6 @@ App.WizardStep9Controller = Em.Controller.extend({ Em.run.once(this, 'updateStatus'); }.observes('[email protected]'), - /** * A flag that gets set with installation failure. * @type {bool} @@ -150,6 +150,24 @@ App.WizardStep9Controller = Em.Controller.extend({ installFailed: false, /** + * Incremental flag that triggers an event in step 9 view to change the tasks related data and icons of hosts. + * @type {number} + */ + logTasksChangesCounter: 0, + + /** + * <code>taskId</code> of current open task + * @type {number} + */ + currentOpenTaskId: 0, + + /** + * <code>requestId</code> of current open task + * @type {number} + */ + currentOpenTaskRequestId: 0, + + /** * Observer function: Updates {status} field of the controller. * @method updateStatus */ @@ -172,24 +190,6 @@ App.WizardStep9Controller = Em.Controller.extend({ }.observes('progress'), /** - * Incremental flag that triggers an event in step 9 view to change the tasks related data and icons of hosts. - * @type {number} - */ - logTasksChangesCounter: 0, - - /** - * <code>taskId</code> of current open task - * @type {number} - */ - currentOpenTaskId: 0, - - /** - * <code>requestId</code> of current open task - * @type {number} - */ - currentOpenTaskRequestId: 0, - - /** * This function is called when a click event happens on Next button of "Install, Start and Test" page * @method submit */ @@ -207,7 +207,6 @@ App.WizardStep9Controller = Em.Controller.extend({ } }, - /** * navigateStep is called by App.WizardStep9View's didInsertElement and "retry" from router. * content.cluster.status can be: @@ -283,7 +282,6 @@ App.WizardStep9Controller = Em.Controller.extend({ this.loadHosts(); }, - /** * Reset status and message of all hosts when retry install * @method resetHostsForRetry @@ -339,6 +337,7 @@ App.WizardStep9Controller = Em.Controller.extend({ */ displayMessage: function (task) { var role = App.format.role(task.role); + /* istanbul ignore next */ switch (task.command) { case 'INSTALL': switch (task.status) { @@ -431,6 +430,7 @@ App.WizardStep9Controller = Em.Controller.extend({ /** * Run start/check services after installation phase. * Does Ajax call to start all services + * @return {$.ajax|null} * @method launchStartServices */ launchStartServices: function () { @@ -465,7 +465,7 @@ App.WizardStep9Controller = Em.Controller.extend({ this.set('numPolls', 6); } - App.ajax.send({ + return App.ajax.send({ name: name, sender: this, data: { @@ -497,7 +497,8 @@ App.WizardStep9Controller = Em.Controller.extend({ }; this.hostHasClientsOnly(false); this.saveClusterStatus(clusterStatus); - } else { + } + else { console.log('ERROR: Error occurred in parsing JSON data'); this.hostHasClientsOnly(true); clusterStatus = { @@ -759,7 +760,8 @@ App.WizardStep9Controller = Em.Controller.extend({ clusterStatus.status = 'STARTED'; var serviceStartTime = App.dateTime(); clusterStatus.installTime = ((parseInt(serviceStartTime) - parseInt(this.get('content.cluster.installStartTime'))) / 60000).toFixed(2); - } else { + } + else { clusterStatus.status = 'START FAILED'; // 'START FAILED' implies to step10 that installation was successful but start failed } this.saveClusterStatus(clusterStatus); @@ -835,9 +837,6 @@ App.WizardStep9Controller = Em.Controller.extend({ var totalProgress = 0; var tasksData = polledData.tasks; console.log("The value of tasksData is: ", tasksData); - if (!tasksData) { - console.log("Step9: ERROR: NO tasks available to process"); - } var requestId = this.get('content.cluster.requestId'); tasksData.setEach('Tasks.request_id', requestId); if (polledData.Requests && polledData.Requests.id && polledData.Requests.id != requestId) { @@ -947,10 +946,13 @@ App.WizardStep9Controller = Em.Controller.extend({ loadCurrentTaskLogSuccessCallback: function (data) { var taskId = this.get('currentOpenTaskId'); if (taskId) { - var currentTask = this.get('hosts').findProperty('name', data.Tasks.host_name).get('logTasks').findProperty('Tasks.id', data.Tasks.id); - if (currentTask) { - currentTask.Tasks.stderr = data.Tasks.stderr; - currentTask.Tasks.stdout = data.Tasks.stdout; + var host = this.get('hosts').findProperty('name', data.Tasks.host_name); + if (host) { + var currentTask = host.get('logTasks').findProperty('Tasks.id', data.Tasks.id); + if (currentTask) { + currentTask.Tasks.stderr = data.Tasks.stderr; + currentTask.Tasks.stdout = data.Tasks.stdout; + } } } this.set('logTasksChangesCounter', this.get('logTasksChangesCounter') + 1); @@ -969,9 +971,10 @@ App.WizardStep9Controller = Em.Controller.extend({ * @param {bool} polling whether to continue polling for status or not * @param {number} requestId * @method getLogsByRequest + * @return {$.ajax|null} */ getLogsByRequest: function (polling, requestId) { - App.ajax.send({ + return App.ajax.send({ name: 'wizard.step9.load_log', sender: this, data: { @@ -1015,22 +1018,15 @@ App.WizardStep9Controller = Em.Controller.extend({ self.loadCurrentTaskLog(); } self.doPolling(); - }, this.POLL_INTERVAL); + }, this.get('POLL_INTERVAL')); } }, /** * Error-callback for get log by request - * @param {object} request - * @param {object} ajaxOptions - * @param {string} error * @method getLogsByRequestErrorCallback */ - getLogsByRequestErrorCallback: function (request, ajaxOptions, error) { - console.log("TRACE: STep9 -> In error function for the GET logs data"); - console.log("TRACE: STep9 -> value of the url is: " + url); - console.log("TRACE: STep9 -> error code status is: " + request.status); - }, + getLogsByRequestErrorCallback: Em.K, /** * Delegates the function call to {getLogsByRequest} with appropriate params @@ -1047,13 +1043,14 @@ App.WizardStep9Controller = Em.Controller.extend({ /** * Check that all components are in INSTALLED state before issuing start command * @method isAllComponentsInstalled + * @return {$.ajax|null} */ isAllComponentsInstalled: function () { if (this.get('content.controllerName') !== 'installerController') { - return; + return null; } var name = 'wizard.step9.installer.get_host_status'; - App.ajax.send({ + return App.ajax.send({ name: name, sender: this, data: { @@ -1109,7 +1106,6 @@ App.WizardStep9Controller = Em.Controller.extend({ * @method isAllComponentsInstalledErrorCallback */ isAllComponentsInstalledErrorCallback: function () { - console.log("ERROR"); var clusterStatus = { status: 'INSTALL FAILED', isStartError: true, @@ -1134,18 +1130,22 @@ App.WizardStep9Controller = Em.Controller.extend({ getComponentMessage: function (componentArr) { var label = ''; componentArr.forEach(function (_component) { - if (_component === componentArr[0]) { + if (componentArr.length === 1) { label = _component; - } else if (_component !== componentArr[componentArr.length - 1]) { // [clients.length - 1] - label = label + ' ' + _component; - if (_component !== componentArr[componentArr.length - 2]) { - label = label + ','; + } + else { + if (_component !== componentArr[componentArr.length - 1]) { // [clients.length - 1] + label = label + ' ' + _component; + if (_component !== componentArr[componentArr.length - 2]) { + label = label + ','; + } + } + else { + label = label + ' ' + Em.I18n.t('and') + ' ' + _component; } - } else { - label = label + ' ' + Em.I18n.t('and') + ' ' + _component; } }, this); - return label; + return label.trim(); }, /** @@ -1156,7 +1156,8 @@ App.WizardStep9Controller = Em.Controller.extend({ saveClusterStatus: function (clusterStatus) { if (!App.testMode) { App.router.get(this.get('content.controllerName')).saveClusterStatus(clusterStatus); - } else { + } + else { this.set('content.cluster', clusterStatus); } }, @@ -1168,8 +1169,8 @@ App.WizardStep9Controller = Em.Controller.extend({ */ saveInstalledHosts: function (context) { if (!App.testMode) { - App.router.get(this.get('content.controllerName')).saveInstalledHosts(context) + App.router.get(this.get('content.controllerName')).saveInstalledHosts(context); } } -}); +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/b96edcf9/ambari-web/app/templates/wizard/step9.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/wizard/step9.hbs b/ambari-web/app/templates/wizard/step9.hbs index 988aa32..307609e 100644 --- a/ambari-web/app/templates/wizard/step9.hbs +++ b/ambari-web/app/templates/wizard/step9.hbs @@ -21,6 +21,7 @@ <h2>{{t installer.step9.header}}</h2> <p class="alert alert-info">{{t installer.step9.body}}</p> + <div id="overallProgress"> <div class="row-fluid"> <div class="span10"> @@ -37,10 +38,10 @@ <div class="box-header"> <div class="pull-left"> {{#if controller.showRetry}} - <a class="btn btn-primary" - href="#" {{action retry}}><i class="icon-repeat icon-white"></i> - {{t common.retry}} - </a> + <a class="btn btn-primary" href="#" {{action retry}}> + <i class="icon-repeat icon-white"></i> + {{t common.retry}} + </a> {{/if}} </div> <!-- filter by host level --> @@ -75,9 +76,9 @@ </thead> <tbody> - {{#if view.pageContent}} - {{#each host in view.pageContent}} - {{#view App.HostStatusView objBinding="host" controllerBinding="controller"}} + {{#if view.pageContent}} + {{#each host in view.pageContent}} + {{#view App.HostStatusView objBinding="host" controllerBinding="controller"}} <td> {{host.name}} </td> @@ -91,50 +92,52 @@ </td> <td> <a {{bindAttr class="view.isFailed:text-error view.isSuccess:text-success view.isWarning:text-warning"}} - href="javascript:void(null)" - data-toggle="modal" {{action hostLogPopup target="view"}}>{{host.message}}</a> + href="javascript:void(null)" + data-toggle="modal" {{action hostLogPopup target="view"}}>{{host.message}}</a> </td> - {{/view}} - {{/each}} - {{else}} + {{/view}} + {{/each}} + {{else}} <tr> <td colspan="3"><p>{{t installer.step3.hosts.noHosts}}</p></td> </tr> - {{/if}} + {{/if}} </tbody> </table> </div> - <div id="hosts"> - <div class="page-bar"> - <div class="selected-hosts-info pull-left"> - {{view.filteredHostsInfo}} - - - <a {{action showAllHosts target="view"}} href="#">{{t tableView.filters.showAll}}</a> - </div> - <div class="items-on-page"> - <label>{{t common.show}}: {{view view.rowsPerPageSelectView selectionBinding="view.displayLength"}}</label> - </div> - <div class="info">{{view.paginationInfo}}</div> - <div class="paging_two_button"> - {{view view.paginationFirst}} - {{view view.paginationLeft}} - {{view view.paginationRight}} - {{view view.paginationLast}} - </div> + <div id="hosts"> + <div class="page-bar"> + <div class="selected-hosts-info pull-left"> + {{view.filteredHostsInfo}} + - + <a {{action showAllHosts target="view"}} href="#">{{t tableView.filters.showAll}}</a> + </div> + <div class="items-on-page"> + <label>{{t common.show}}: {{view view.rowsPerPageSelectView selectionBinding="view.displayLength"}}</label> + </div> + <div class="info">{{view.paginationInfo}}</div> + <div class="paging_two_button"> + {{view view.paginationFirst}} + {{view view.paginationLeft}} + {{view view.paginationRight}} + {{view view.paginationLast}} </div> </div> + </div> </div> <div> {{#if view.resultMsg}} <p {{bindAttr class="view.resultMsgColor :alert"}}>{{view.resultMsg}} - {{#if view.isHostHeartbeatLost}} - <a href="javascript:void(null)" data-toggle="modal" {{action hostWithInstallFailed target="view"}}>{{t common.showDetails}}</a> - {{/if}} + {{#if view.isHostHeartbeatLost}} + <a href="javascript:void(null)" + data-toggle="modal" {{action hostWithInstallFailed target="view"}}>{{t common.showDetails}}</a> + {{/if}} </p> {{/if}} <div class="btn-area"> - <button class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action submit target="controller"}}>{{t common.next}} →</button> + <button + class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action submit target="controller"}}>{{t common.next}} →</button> </div> </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/b96edcf9/ambari-web/app/templates/wizard/step9/step9HostTasksLogPopup.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/wizard/step9/step9HostTasksLogPopup.hbs b/ambari-web/app/templates/wizard/step9/step9HostTasksLogPopup.hbs new file mode 100644 index 0000000..2671bbb --- /dev/null +++ b/ambari-web/app/templates/wizard/step9/step9HostTasksLogPopup.hbs @@ -0,0 +1,90 @@ +{{! +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +}} + +{{#if view.isHeartbeatLost}} + <div> + {{t installer.step9.host.heartbeat_lost_popup}} + </div> +{{else}} + {{#if view.isNoTasksScheduled}} + {{t installer.step9.host.status.noTasks}} + {{else}} + <div {{bindAttr class="view.isLogWrapHidden::hidden :task-list-main-warp"}}> + <div class="task-top-wrap"> + <div class="task-name-top task-detail-log-rolename">{{t common.tasks}}</div> + <div class="select-wrap"> + {{t common.show}}: + {{view Ember.Select + contentBinding="view.categories" + optionValuePath="content.value" + optionLabelPath="content.label" + selectionBinding="view.category" + }} + </div> + </div> + <div id="host-log"> + {{#each taskInfo in view.tasks}} + <div {{bindAttr class="taskInfo.isVisible::hidden :log-list-wrap"}}> + <div {{action toggleTaskLog taskInfo}} class="task-list-line-cursor"> + <div class="operation-name-icon-wrap"> + <i {{bindAttr class="taskInfo.status taskInfo.icon"}}></i> + <a href="#"> + {{taskInfo.role}} {{taskInfo.command}} + </a> + </div> + <div class="show-details"><i class="icon-caret-right"></i></div> + </div> + </div> + {{/each}} + {{#if view.isEmptyList}} + <div class="log-list-wrap">{{t installer.step9.hostLog.popup.noTasksToShow}}</div> + {{/if}} + </div> + </div> + + <div {{bindAttr class="view.isLogWrapHidden:hidden :task-detail-info"}}> + <div class="task-top-wrap"> + <a class="task-detail-back" href="javascript:void(null)" {{action backToTaskList}} ><i + class="icon-arrow-left"></i> {{t common.tasks}}</a> + + <div> + <i {{bindAttr class="view.openedTask.status :task-detail-status-ico view.openedTask.icon"}} + class="task-detail-status-ico"></i> + <span class="task-detail-log-rolename">{{view.openedTask.role}} {{view.openedTask.command}}</span> + </div> + <div class="task-detail-ico-wrap"> + <a title="Click to Copy" {{action "textTrigger" taskInfo target="view"}} class="task-detail-copy"><i + class="icon-copy"></i> {{t common.copy}}</a> + <a title="Open in New Window" {{action openTaskLogInDialog}} class="task-detail-open-dialog"><i + class="icon-external-link"></i> {{t common.open}}</a> + </div> + </div> + <div class="task-detail-log-info"> + <div class="content-area"> + <div class="task-detail-log-clipboard-wrap"></div> + <div class="task-detail-log-maintext"> + <h5>stderr: <span class="muted">{{view.openedTask.errorLog}} </span></h5> + <pre class="stderr">{{view.openedTask.stderr}}</pre> + <h5>stdout: <span class="muted"> {{view.openedTask.outputLog}} </span></h5> + <pre class="stdout">{{view.openedTask.stdout}}</pre> + </div> + </div> + </div> + </div> + {{/if}} +{{/if}} http://git-wip-us.apache.org/repos/asf/ambari/blob/b96edcf9/ambari-web/app/templates/wizard/step9/step9_install_host_popup.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/wizard/step9/step9_install_host_popup.hbs b/ambari-web/app/templates/wizard/step9/step9_install_host_popup.hbs new file mode 100644 index 0000000..5da8642 --- /dev/null +++ b/ambari-web/app/templates/wizard/step9/step9_install_host_popup.hbs @@ -0,0 +1,40 @@ +{{! +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +}} + +<div id="install-fail-popup" class="pre-scrollable"> + <table class="table table-striped"> + <thead> + <tr> + <th class="span3">{{t common.host}}</th> + <th class="span3">{{t common.components}}</th> + </tr> + </thead> + <tbody> + {{#each host in view.failedHosts}} + <tr> + <td> + {{host.hostName}} + </td> + <td> + {{host.componentNames}} + </td> + </tr> + {{/each}} + </tbody> + </table> +</div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/b96edcf9/ambari-web/app/templates/wizard/step9HostTasksLogPopup.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/wizard/step9HostTasksLogPopup.hbs b/ambari-web/app/templates/wizard/step9HostTasksLogPopup.hbs deleted file mode 100644 index 2671bbb..0000000 --- a/ambari-web/app/templates/wizard/step9HostTasksLogPopup.hbs +++ /dev/null @@ -1,90 +0,0 @@ -{{! -* Licensed to the Apache Software Foundation (ASF) under one -* or more contributor license agreements. See the NOTICE file -* distributed with this work for additional information -* regarding copyright ownership. The ASF licenses this file -* to you under the Apache License, Version 2.0 (the -* "License"); you may not use this file except in compliance -* with the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -}} - -{{#if view.isHeartbeatLost}} - <div> - {{t installer.step9.host.heartbeat_lost_popup}} - </div> -{{else}} - {{#if view.isNoTasksScheduled}} - {{t installer.step9.host.status.noTasks}} - {{else}} - <div {{bindAttr class="view.isLogWrapHidden::hidden :task-list-main-warp"}}> - <div class="task-top-wrap"> - <div class="task-name-top task-detail-log-rolename">{{t common.tasks}}</div> - <div class="select-wrap"> - {{t common.show}}: - {{view Ember.Select - contentBinding="view.categories" - optionValuePath="content.value" - optionLabelPath="content.label" - selectionBinding="view.category" - }} - </div> - </div> - <div id="host-log"> - {{#each taskInfo in view.tasks}} - <div {{bindAttr class="taskInfo.isVisible::hidden :log-list-wrap"}}> - <div {{action toggleTaskLog taskInfo}} class="task-list-line-cursor"> - <div class="operation-name-icon-wrap"> - <i {{bindAttr class="taskInfo.status taskInfo.icon"}}></i> - <a href="#"> - {{taskInfo.role}} {{taskInfo.command}} - </a> - </div> - <div class="show-details"><i class="icon-caret-right"></i></div> - </div> - </div> - {{/each}} - {{#if view.isEmptyList}} - <div class="log-list-wrap">{{t installer.step9.hostLog.popup.noTasksToShow}}</div> - {{/if}} - </div> - </div> - - <div {{bindAttr class="view.isLogWrapHidden:hidden :task-detail-info"}}> - <div class="task-top-wrap"> - <a class="task-detail-back" href="javascript:void(null)" {{action backToTaskList}} ><i - class="icon-arrow-left"></i> {{t common.tasks}}</a> - - <div> - <i {{bindAttr class="view.openedTask.status :task-detail-status-ico view.openedTask.icon"}} - class="task-detail-status-ico"></i> - <span class="task-detail-log-rolename">{{view.openedTask.role}} {{view.openedTask.command}}</span> - </div> - <div class="task-detail-ico-wrap"> - <a title="Click to Copy" {{action "textTrigger" taskInfo target="view"}} class="task-detail-copy"><i - class="icon-copy"></i> {{t common.copy}}</a> - <a title="Open in New Window" {{action openTaskLogInDialog}} class="task-detail-open-dialog"><i - class="icon-external-link"></i> {{t common.open}}</a> - </div> - </div> - <div class="task-detail-log-info"> - <div class="content-area"> - <div class="task-detail-log-clipboard-wrap"></div> - <div class="task-detail-log-maintext"> - <h5>stderr: <span class="muted">{{view.openedTask.errorLog}} </span></h5> - <pre class="stderr">{{view.openedTask.stderr}}</pre> - <h5>stdout: <span class="muted"> {{view.openedTask.outputLog}} </span></h5> - <pre class="stdout">{{view.openedTask.stdout}}</pre> - </div> - </div> - </div> - </div> - {{/if}} -{{/if}} http://git-wip-us.apache.org/repos/asf/ambari/blob/b96edcf9/ambari-web/app/templates/wizard/step9_install_host_popup.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/wizard/step9_install_host_popup.hbs b/ambari-web/app/templates/wizard/step9_install_host_popup.hbs deleted file mode 100644 index 5da8642..0000000 --- a/ambari-web/app/templates/wizard/step9_install_host_popup.hbs +++ /dev/null @@ -1,40 +0,0 @@ -{{! -* Licensed to the Apache Software Foundation (ASF) under one -* or more contributor license agreements. See the NOTICE file -* distributed with this work for additional information -* regarding copyright ownership. The ASF licenses this file -* to you under the Apache License, Version 2.0 (the -* "License"); you may not use this file except in compliance -* with the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -}} - -<div id="install-fail-popup" class="pre-scrollable"> - <table class="table table-striped"> - <thead> - <tr> - <th class="span3">{{t common.host}}</th> - <th class="span3">{{t common.components}}</th> - </tr> - </thead> - <tbody> - {{#each host in view.failedHosts}} - <tr> - <td> - {{host.hostName}} - </td> - <td> - {{host.componentNames}} - </td> - </tr> - {{/each}} - </tbody> - </table> -</div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/b96edcf9/ambari-web/app/views.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js index 2b48b42..6555313 100644 --- a/ambari-web/app/views.js +++ b/ambari-web/app/views.js @@ -257,6 +257,7 @@ require('views/wizard/step6_view'); require('views/wizard/step7_view'); require('views/wizard/step8_view'); require('views/wizard/step9_view'); +require('views/wizard/step9/hostLogPopupBody_view'); require('views/wizard/step10_view'); require('views/wizard/stack_upgrade/step1_view'); require('views/wizard/stack_upgrade/step2_view'); http://git-wip-us.apache.org/repos/asf/ambari/blob/b96edcf9/ambari-web/app/views/wizard/step9/hostLogPopupBody_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/wizard/step9/hostLogPopupBody_view.js b/ambari-web/app/views/wizard/step9/hostLogPopupBody_view.js new file mode 100644 index 0000000..dd05b59 --- /dev/null +++ b/ambari-web/app/views/wizard/step9/hostLogPopupBody_view.js @@ -0,0 +1,264 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var App = require('app'); +var date = require('utils/date'); + +App.WizardStep9HostLogPopupBodyView = Em.View.extend({ + + templateName: require('templates/wizard/step9/step9HostTasksLogPopup'), + + /** + * Does host lost heartbeat + * @type {bool} + */ + isHeartbeatLost: function() { + return (this.get('parentView.host.status') === 'heartbeat_lost'); + }.property('parentView.host.status'), + + /** + * Does host doesn't have scheduled tasks for install + * @type {bool} + */ + isNoTasksScheduled: function() { + return this.get('parentView.host.isNoTasksForInstall'); + }.property('parentView.host.isNoTasksForInstall'), + + /** + * Is log-box hidden + * @type {bool} + */ + isLogWrapHidden: true, + + /** + * Is log-textarea visible + * @type {bool} + */ + showTextArea: false, + + /** + * No tasks shown + * @type {bool} + */ + isEmptyList: true, + + /** + * Checks if no visible tasks are in popup + * @method visibleTasks + */ + visibleTasks: function () { + this.set("isEmptyList", true); + if (this.get('category.value')) { + var filter = this.get('category.value'); + var tasks = this.get('tasks'); + tasks.setEach("isVisible", false); + + if (filter == "all") { + tasks.setEach("isVisible", true); + } + else if (filter == "pending") { + tasks.filterProperty("status", "pending").setEach("isVisible", true); + tasks.filterProperty("status", "queued").setEach("isVisible", true); + } + else if (filter == "in_progress") { + tasks.filterProperty("status", "in_progress").setEach("isVisible", true); + } + else if (filter == "failed") { + tasks.filterProperty("status", "failed").setEach("isVisible", true); + } + else if (filter == "completed") { + tasks.filterProperty("status", "completed").setEach("isVisible", true); + } + else if (filter == "aborted") { + tasks.filterProperty("status", "aborted").setEach("isVisible", true); + } + else if (filter == "timedout") { + tasks.filterProperty("status", "timedout").setEach("isVisible", true); + } + + if (tasks.filterProperty("isVisible", true).length > 0) { + this.set("isEmptyList", false); + } + } + }.observes('category', 'tasks'), + + /** + * List categories (implements possible values for task status) + * @type {Em.Object[]} + */ + categories: [ + Em.Object.create({value: 'all', label: Em.I18n.t('installer.step9.hostLog.popup.categories.all') }), + Em.Object.create({value: 'pending', label: Em.I18n.t('installer.step9.hostLog.popup.categories.pending')}), + Em.Object.create({value: 'in_progress', label: Em.I18n.t('installer.step9.hostLog.popup.categories.in_progress')}), + Em.Object.create({value: 'failed', label: Em.I18n.t('installer.step9.hostLog.popup.categories.failed') }), + Em.Object.create({value: 'completed', label: Em.I18n.t('installer.step9.hostLog.popup.categories.completed') }), + Em.Object.create({value: 'aborted', label: Em.I18n.t('installer.step9.hostLog.popup.categories.aborted') }), + Em.Object.create({value: 'timedout', label: Em.I18n.t('installer.step9.hostLog.popup.categories.timedout') }) + ], + + /** + * Current category + * @type {Em.Object} + */ + category: null, + + /** + * List of tasks + * @type {Em.Object[]} + */ + tasks: function () { + var tasksArr = []; + var host = this.get('parentView.host'); + var tasks = this.getStartedTasks(host); + tasks = tasks.sortProperty('Tasks.id'); + if (tasks.length) { + tasks.forEach(function (_task) { + var taskInfo = Em.Object.create({}); + taskInfo.set('id', _task.Tasks.id); + taskInfo.set('requestId', _task.Tasks.request_id); + taskInfo.set('command', _task.Tasks.command.toLowerCase() === 'service_check' ? '' : _task.Tasks.command.toLowerCase()); + taskInfo.set('status', App.format.taskStatus(_task.Tasks.status)); + taskInfo.set('role', App.format.role(_task.Tasks.role)); + taskInfo.set('stderr', _task.Tasks.stderr); + taskInfo.set('stdout', _task.Tasks.stdout); + taskInfo.set('startTime', date.startTime(_task.Tasks.start_time)); + taskInfo.set('duration', date.durationSummary(_task.Tasks.start_time, _task.Tasks.end_time)); + taskInfo.set('isVisible', true); + taskInfo.set('icon', ''); + taskInfo.set('hostName', _task.Tasks.host_name); + taskInfo.set('outputLog', Em.I18n.t('common.hostLog.popup.logDir.path') + Em.I18n.t('common.hostLog.popup.outputLog.value').format(_task.Tasks.id)); + taskInfo.set('errorLog', Em.I18n.t('common.hostLog.popup.logDir.path') + Em.I18n.t('common.hostLog.popup.errorLog.value').format(_task.Tasks.id)); + if (taskInfo.get('status') == 'pending' || taskInfo.get('status') == 'queued') { + taskInfo.set('icon', 'icon-cog'); + } else if (taskInfo.get('status') == 'in_progress') { + taskInfo.set('icon', 'icon-cogs'); + } else if (taskInfo.get('status') == 'completed') { + taskInfo.set('icon', ' icon-ok'); + } else if (taskInfo.get('status') == 'failed') { + taskInfo.set('icon', 'icon-exclamation-sign'); + } else if (taskInfo.get('status') == 'aborted') { + taskInfo.set('icon', 'icon-minus'); + } else if (taskInfo.get('status') == 'timedout') { + taskInfo.set('icon', 'icon-time'); + } + tasksArr.push(taskInfo); + }, this); + } + return tasksArr; + }.property('parentView.c.logTasksChangesCounter'), + + /** + * Navigate to task list from task view + * @method backToTaskList + */ + backToTaskList: function () { + this.destroyClipBoard(); + this.set("isLogWrapHidden", true); + }, + + /** + * Get list of host's started tasks + * @param {object} host + * @returns {object[]} + * @method getStartedTasks + */ + getStartedTasks: function (host) { + return host.logTasks.filter(function (task) { + return task.Tasks.status; + }); + }, + + /** + * Open new window with task's log + * @method openTaskLogInDialog + */ + openTaskLogInDialog: function () { + var newwindow = window.open(); + var newdocument = newwindow.document; + newdocument.write($(".task-detail-log-info").html()); + newdocument.close(); + }, + + /** + * Currently open task + * @type {Em.Object} + */ + openedTask: function () { + return this.get('tasks').findProperty('id', this.get('parentView.c.currentOpenTaskId')) + }.property('parentView.c.currentOpenTaskId', 'tasks.@each'), + + /** + * Click-handler for toggle task's log view (textarea to box and back) + * @param {object} event + * @method toggleTaskLog + */ + toggleTaskLog: function (event) { + if (this.get('isLogWrapHidden')) { + var taskInfo = event.context; + this.set("isLogWrapHidden", false); + this.set('parentView.c.currentOpenTaskId', taskInfo.id); + this.set('parentView.c.currentOpenTaskRequestId', taskInfo.requestId); + this.get('parentView.c').loadCurrentTaskLog(); + $(".modal").scrollTop(0); + $(".modal-body").scrollTop(0); + } + else { + this.set("isLogWrapHidden", true); + this.set('parentView.c.currentOpenTaskId', 0); + this.set('parentView.c.currentOpenTaskRequestId', 0); + } + }, + + /** + * Create (if doesn't exist) or destroy (if exists) clipboard textarea + * @method textTrigger + */ + textTrigger: function () { + if ($(".task-detail-log-clipboard").length > 0) { + this.destroyClipBoard(); + } + else { + this.createClipBoard(); + } + }, + + /** + * Create clipboard with task's log + * @method createClipBoard + */ + createClipBoard: function () { + var log = $(".task-detail-log-maintext"); + $(".task-detail-log-clipboard-wrap").html('<textarea class="task-detail-log-clipboard"></textarea>'); + $(".task-detail-log-clipboard") + .html("stderr: \n" + $(".stderr").html() + "\n stdout:\n" + $(".stdout").html()) + .css("display", "block") + .width(log.width()) + .height(log.height()) + .select(); + log.css("display", "none") + }, + + /** + * Destroy clipboard with task's log + * @method destroyClipBoard + */ + destroyClipBoard: function () { + $(".task-detail-log-clipboard").remove(); + $(".task-detail-log-maintext").css("display", "block"); + } +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/b96edcf9/ambari-web/app/views/wizard/step9_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/wizard/step9_view.js b/ambari-web/app/views/wizard/step9_view.js index 1e08f26..ec64530 100644 --- a/ambari-web/app/views/wizard/step9_view.js +++ b/ambari-web/app/views/wizard/step9_view.js @@ -22,21 +22,51 @@ var date = require('utils/date'); App.WizardStep9View = App.TableView.extend({ templateName: require('templates/wizard/step9'), + + /** + * Overall progress-bar color + * @type {string} + */ barColor: '', + + /** + * Overall result message + * @type {string} + */ resultMsg: '', + + /** + * Overall message color + * @type {string} + */ resultMsgColor: '', + + /** + * When progress is 100, step is completed + * @type {bool} + */ isStepCompleted: function() { return (this.get('controller.progress') === '100'); }.property('controller.progress'), + /** + * Number of visible hosts + * @type {string} + */ displayLength: "25", + /** + * Same to <code>controller.hosts</code> + * @type {object[]} + */ content: function () { return this.get('controller.hosts'); }.property('controller.hosts'), - filteredContent: [], - + /** + * Active category + * @type {Ember.Object} + */ selectedCategory: function() { return this.get('categories').findProperty('isActive'); }.property('[email protected]'), @@ -62,9 +92,10 @@ App.WizardStep9View = App.TableView.extend({ return this.get('isActive') ? 'active' : ''; }.property('isActive') }), + /** - * computed property creates the category objects on the load of the page and sets 'All' as the active category - * @Returns: All created categories which are binded and iterated in the template + * Domputed property creates the category objects on the load of the page and sets 'All' as the active category + * @Returns {Em.Object[]} All created categories which are binded and iterated in the template */ categories: function () { return [ @@ -76,13 +107,49 @@ App.WizardStep9View = App.TableView.extend({ ]; }.property(), + /** + * True if <code>controller.hostsWithHeartbeatLost</code> contains some values + * @type {bool} + */ + isHostHeartbeatLost: function () { + return (this.get('controller.hostsWithHeartbeatLost').length > 0); + }.property('controller.hostsWithHeartbeatLost.@each'), + + /** + * Css-string to overall progress-bar width-property + * @type {string} + */ + barWidth: function () { + var controller = this.get('controller'); + return 'width: ' + controller.get('progress') + '%;'; + }.property('controller.progress'), + + /** + * Filter hosts info shown up on bottom of the box. Set by filter function, when 'seletedCategory' changed + * @type {string} + */ + filteredHostsInfo: '', + + /** + * Message for overall progress + * @type {string} + */ + progressMessage: function () { + return Em.I18n.t('installer.step9.overallProgress').format(this.get('controller.progress')); + }.property('controller.progress'), + + /** + * Run <code>countCategoryHosts</code>, <code>filter</code> only once + * @method hostStatusObserver + */ hostStatusObserver: function(){ - Ember.run.once(this, 'countCategoryHosts'); - Ember.run.once(this, 'filter'); + Em.run.once(this, 'countCategoryHosts'); + Em.run.once(this, 'filter'); }.observes('[email protected]'), /** - * count each category hosts to update label + * Count each category hosts to update label + * @method countCategoryHosts */ countCategoryHosts: function () { var counters = { @@ -109,7 +176,8 @@ App.WizardStep9View = App.TableView.extend({ }, /** - * filter hosts by category + * Filter hosts by category + * @method filter */ filter: function () { var self = this; @@ -136,12 +204,8 @@ App.WizardStep9View = App.TableView.extend({ }.observes('selectedCategory'), /** - * filter hosts info shown up on bottom of the box. Set by filter function, when 'seletedCategory' changed - */ - filteredHostsInfo: '', - - /** * On click handler for 'show all' link + * @method showAllHosts */ showAllHosts: function () { this.get('categories').forEach(function (category) { @@ -152,6 +216,7 @@ App.WizardStep9View = App.TableView.extend({ /** * Trigger on Category click * @param {Object} event + * @method selectCategory */ selectCategory: function (event) { var categoryStatus = event.context.get('hostStatus'); @@ -161,24 +226,15 @@ App.WizardStep9View = App.TableView.extend({ }, didInsertElement: function () { - var controller = this.get('controller'); this.onStatus(); - controller.navigateStep(); + this.get('controller').navigateStep(); }, - isHostHeartbeatLost: function () { - return (this.get('controller.hostsWithHeartbeatLost').length > 0); - }.property('controller.hostsWithHeartbeatLost.@each'), - - barWidth: function () { - var controller = this.get('controller'); - return 'width: ' + controller.get('progress') + '%;'; - }.property('controller.progress'), - - progressMessage: function () { - return Em.I18n.t('installer.step9.overallProgress').format(this.get('controller.progress')); - }.property('controller.progress'), - + /** + * Set <code>resultMsg</code>, <code>resultMsg</code>, <code>resultMsgColor</code> according to + * <code>controller.status</code>, <code>controller.startCallFailed</code>, <code>isHostHeartbeatLost</code> + * @method onStatus + */ onStatus: function () { if (this.get('controller.status') === 'info') { this.set('resultMsg', ''); @@ -208,17 +264,21 @@ App.WizardStep9View = App.TableView.extend({ } }.observes('controller.status', 'controller.startCallFailed','isHostHeartbeatLost'), - - hostWithInstallFailed: function (event, context) { + /** + * Show popup with info about failed hosts + * @return {App.ModalPopup} + * @method hostWithInstallFailed + */ + hostWithInstallFailed: function () { var controller = this.get('controller'); - App.ModalPopup.show({ + return App.ModalPopup.show({ header: Em.I18n.t('installer.step9.host.heartbeat_lost.header'), classNames: ['sixty-percent-width-modal'], autoHeight: false, secondary: null, - bodyClass: Ember.View.extend({ - templateName: require('templates/wizard/step9_install_host_popup'), + bodyClass: Em.View.extend({ + templateName: require('templates/wizard/step9/step9_install_host_popup'), c: controller, failedHosts: function () { return controller.get('hostsWithHeartbeatLost'); @@ -226,28 +286,80 @@ App.WizardStep9View = App.TableView.extend({ }) }); } + }); App.HostStatusView = Em.View.extend({ + tagName: 'tr', + /** * Current host + * @type {Em.Object} */ obj: null, + /** * wizardStep9Controller + * @type {App.WizardStep9Controller} */ controller: null, - barColor: '', - didInsertElement: function () { - this.onStatus(); - }, + /** + * Progress-bar color for current host + * @type {string} + */ + barColor: '', + /** + * Css-string to progress-bar width-property + * @type {string} + */ barWidth: function () { return 'width: ' + this.get('obj.progress') + '%;'; }.property('obj.progress'), + /** + * Is current host failed + * @type {bool} + */ + isFailed: function () { + return (this.get('isHostCompleted') && (this.get('obj.status') === 'failed' || this.get('obj.status') === 'heartbeat_lost')); + }.property('obj.status', 'isHostCompleted'), + + /** + * Is current host successfully installed + * @type {bool} + */ + isSuccess: function () { + return (this.get('isHostCompleted') && this.get('obj.status') === 'success'); + }.property('obj.status', 'isHostCompleted'), + + /** + * Current host has warnings + * @type {bool} + */ + isWarning: function () { + return(this.get('isHostCompleted') && this.get('obj.status') === 'warning'); + }.property('obj.status', 'isHostCompleted'), + + /** + * Current host completed all its tasks + * @type {bool} + */ + isHostCompleted: function () { + return this.get('obj.progress') == 100; + }.property('obj.progress'), + + didInsertElement: function () { + this.onStatus(); + }, + + /** + * Set <code>barColor</code>, <code>obj.progress</code>, <code>obj.message</code> according to + * <code>obj.status</code>, <code>obj.progress</code>, <code>controller.progress</code> + * @method onStatus + */ onStatus: function () { if (this.get('obj.status') === 'info') { this.set('barColor', 'progress-info'); @@ -272,37 +384,34 @@ App.HostStatusView = Em.View.extend({ } }.observes('obj.status', 'obj.progress', 'controller.progress'), - isFailed: function () { - return (this.get('isHostCompleted') && (this.get('obj.status') === 'failed' || this.get('obj.status') === 'heartbeat_lost')); - }.property('obj.status', 'isHostCompleted'), - - isSuccess: function () { - return (this.get('isHostCompleted') && this.get('obj.status') === 'success'); - }.property('obj.status', 'isHostCompleted'), - - isWarning: function () { - return(this.get('isHostCompleted') && this.get('obj.status') === 'warning'); - }.property('obj.status', 'isHostCompleted'), - - isHostCompleted: function () { - return this.get('obj.progress') == 100; - }.property('obj.progress'), - - hostLogPopup: function (event, context) { + /** + * Show popup with host logs + * @return {App.ModalPopup} + * @method hostLogPopup + */ + hostLogPopup: function () { var controller = this.get('controller'); var host = this.get('obj'); - App.ModalPopup.show({ + return App.ModalPopup.show({ + header: host.get('name'), + classNames: ['sixty-percent-width-modal'], + autoHeight: false, + secondary: null, + /** * Current host + * @type {Em.Object} */ host: host, + /** * wizardStep9Controller + * @type {App.WizardStep9Controller} */ c: controller, @@ -311,175 +420,7 @@ App.HostStatusView = Em.View.extend({ this.hide(); }, - bodyClass: Ember.View.extend({ - templateName: require('templates/wizard/step9HostTasksLogPopup'), - isHeartbeatLost: function() { - return (host.get('status') === 'heartbeat_lost'); - }.property('host.status'), - isNoTasksScheduled: function() { - return host.get('isNoTasksForInstall'); - }.property('host.isNoTasksForInstall'), - - isLogWrapHidden: true, - - showTextArea: false, - - isEmptyList: true, - - visibleTasks: function () { - this.set("isEmptyList", true); - if (this.get('category.value')) { - var filter = this.get('category.value'); - var tasks = this.get('tasks'); - tasks.setEach("isVisible", false); - - if (filter == "all") { - tasks.setEach("isVisible", true); - } - else if (filter == "pending") { - tasks.filterProperty("status", "pending").setEach("isVisible", true); - tasks.filterProperty("status", "queued").setEach("isVisible", true); - } - else if (filter == "in_progress") { - tasks.filterProperty("status", "in_progress").setEach("isVisible", true); - } - else if (filter == "failed") { - tasks.filterProperty("status", "failed").setEach("isVisible", true); - } - else if (filter == "completed") { - tasks.filterProperty("status", "completed").setEach("isVisible", true); - } - else if (filter == "aborted") { - tasks.filterProperty("status", "aborted").setEach("isVisible", true); - } - else if (filter == "timedout") { - tasks.filterProperty("status", "timedout").setEach("isVisible", true); - } - - if (tasks.filterProperty("isVisible", true).length > 0) { - this.set("isEmptyList", false); - } - } - }.observes('category', 'tasks'), - - categories: [ - Ember.Object.create({value: 'all', label: Em.I18n.t('installer.step9.hostLog.popup.categories.all') }), - Ember.Object.create({value: 'pending', label: Em.I18n.t('installer.step9.hostLog.popup.categories.pending')}), - Ember.Object.create({value: 'in_progress', label: Em.I18n.t('installer.step9.hostLog.popup.categories.in_progress')}), - Ember.Object.create({value: 'failed', label: Em.I18n.t('installer.step9.hostLog.popup.categories.failed') }), - Ember.Object.create({value: 'completed', label: Em.I18n.t('installer.step9.hostLog.popup.categories.completed') }), - Ember.Object.create({value: 'aborted', label: Em.I18n.t('installer.step9.hostLog.popup.categories.aborted') }), - Ember.Object.create({value: 'timedout', label: Em.I18n.t('installer.step9.hostLog.popup.categories.timedout') }) - ], - - category: null, - - tasks: function () { - var tasksArr = []; - var host = this.get('parentView.host'); - var tasks = this.getStartedTasks(host); - tasks = tasks.sortProperty('Tasks.id'); - if (tasks.length) { - tasks.forEach(function (_task) { - var taskInfo = Ember.Object.create({}); - taskInfo.set('id', _task.Tasks.id); - taskInfo.set('requestId', _task.Tasks.request_id); - taskInfo.set('command', _task.Tasks.command.toLowerCase() === 'service_check' ? '' : _task.Tasks.command.toLowerCase()); - taskInfo.set('status', App.format.taskStatus(_task.Tasks.status)); - taskInfo.set('role', App.format.role(_task.Tasks.role)); - taskInfo.set('stderr', _task.Tasks.stderr); - taskInfo.set('stdout', _task.Tasks.stdout); - taskInfo.set('startTime', date.startTime(_task.Tasks.start_time)); - taskInfo.set('duration', date.durationSummary(_task.Tasks.start_time, _task.Tasks.end_time)); - taskInfo.set('isVisible', true); - taskInfo.set('icon', ''); - taskInfo.set('hostName', _task.Tasks.host_name); - taskInfo.set('outputLog', Em.I18n.t('common.hostLog.popup.logDir.path') + Em.I18n.t('common.hostLog.popup.outputLog.value').format(_task.Tasks.id)); - taskInfo.set('errorLog', Em.I18n.t('common.hostLog.popup.logDir.path') + Em.I18n.t('common.hostLog.popup.errorLog.value').format(_task.Tasks.id)); - if (taskInfo.get('status') == 'pending' || taskInfo.get('status') == 'queued') { - taskInfo.set('icon', 'icon-cog'); - } else if (taskInfo.get('status') == 'in_progress') { - taskInfo.set('icon', 'icon-cogs'); - } else if (taskInfo.get('status') == 'completed') { - taskInfo.set('icon', ' icon-ok'); - } else if (taskInfo.get('status') == 'failed') { - taskInfo.set('icon', 'icon-exclamation-sign'); - } else if (taskInfo.get('status') == 'aborted') { - taskInfo.set('icon', 'icon-minus'); - } else if (taskInfo.get('status') == 'timedout') { - taskInfo.set('icon', 'icon-time'); - } - tasksArr.push(taskInfo); - }, this); - } - return tasksArr; - }.property('parentView.c.logTasksChangesCounter'), - - backToTaskList: function (event, context) { - this.destroyClipBoard(); - this.set("isLogWrapHidden", true); - }, - - getStartedTasks: function (host) { - return host.logTasks.filter(function (task) { - return task.Tasks.status; - }); - }, - - openTaskLogInDialog: function () { - var newwindow = window.open(); - var newdocument = newwindow.document; - newdocument.write($(".task-detail-log-info").html()); - newdocument.close(); - }, - - openedTask: function () { - return this.get('tasks').findProperty('id', this.get('parentView.c.currentOpenTaskId')) - }.property('parentView.c.currentOpenTaskId', 'tasks.@each'), - - toggleTaskLog: function (event, context) { - if (this.get('isLogWrapHidden')) { - var taskInfo = event.context; - this.set("isLogWrapHidden", false); - this.set('parentView.c.currentOpenTaskId', taskInfo.id); - this.set('parentView.c.currentOpenTaskRequestId', taskInfo.requestId); - this.get('parentView.c').loadCurrentTaskLog(); - $(".modal").scrollTop(0); - $(".modal-body").scrollTop(0); - } - else { - this.set("isLogWrapHidden", true); - this.set('parentView.c.currentOpenTaskId', 0); - this.set('parentView.c.currentOpenTaskRequestId', 0); - } - }, - - textTrigger: function (event) { - if ($(".task-detail-log-clipboard").length > 0) { - this.destroyClipBoard(); - } - else { - this.createClipBoard(); - } - }, - - createClipBoard: function () { - var log = $(".task-detail-log-maintext"); - $(".task-detail-log-clipboard-wrap").html('<textarea class="task-detail-log-clipboard"></textarea>'); - $(".task-detail-log-clipboard") - .html("stderr: \n" + $(".stderr").html() + "\n stdout:\n" + $(".stdout").html()) - .css("display", "block") - .width(log.width()) - .height(log.height()) - .select(); - log.css("display", "none") - }, - - destroyClipBoard: function () { - $(".task-detail-log-clipboard").remove(); - $(".task-detail-log-maintext").css("display", "block"); - } - }) + bodyClass: App.WizardStep9HostLogPopupBodyView }); }
