Repository: ambari Updated Branches: refs/heads/branch-2.1 154c98b2c -> c04518272
AMBARI-13393. Express Upgrade: UX changes for upgrade method selections window.(xiwang) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c0451827 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c0451827 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c0451827 Branch: refs/heads/branch-2.1 Commit: c045182729f0b418b1ba55c1d92ceeb85338f8e6 Parents: 154c98b Author: Xi Wang <[email protected]> Authored: Fri Sep 18 15:09:03 2015 -0700 Committer: Xi Wang <[email protected]> Committed: Tue Oct 13 18:23:31 2015 -0700 ---------------------------------------------------------------------- .../main/admin/stack_and_upgrade_controller.js | 282 ++++++++++++++++++- ambari-web/app/messages.js | 17 +- ambari-web/app/routes/stack_upgrade_routes.js | 2 +- ambari-web/app/styles/stack_versions.less | 127 +++++++++ .../stack_upgrade/stack_upgrade_wizard.hbs | 3 + .../admin/stack_upgrade/upgrade_options.hbs | 49 ++++ ambari-web/app/utils/ajax/ajax.js | 24 +- .../common/modal_popups/cluster_check_popup.js | 55 ++++ .../admin/stack_and_upgrade_controller_test.js | 64 ++++- 9 files changed, 595 insertions(+), 28 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/c0451827/ambari-web/app/controllers/main/admin/stack_and_upgrade_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/stack_and_upgrade_controller.js b/ambari-web/app/controllers/main/admin/stack_and_upgrade_controller.js index 880976f..8998055 100644 --- a/ambari-web/app/controllers/main/admin/stack_and_upgrade_controller.js +++ b/ambari-web/app/controllers/main/admin/stack_and_upgrade_controller.js @@ -46,6 +46,18 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage, upgradeVersion: null, /** + * @type {string} + * @default null + */ + upgradeTypeDisplayName: null, + + /** + * @type {object} + * @default null + */ + failuresTolerance: null, + + /** * @type {boolean} * @default false */ @@ -65,6 +77,30 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage, targetVersions: [], /** + * methods through which cluster could be upgraded, "allowed" indicated if the method is allowed + * by stack upgrade path + * @type {Array} + */ + upgradeMethods: [ + Em.Object.create({ + displayName: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.RU.title'), + type: 'ROLLING', + icon: "icon-dashboard", + description: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.RU.description'), + selected: false, + allowed: true + }), + Em.Object.create({ + displayName: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.EU.title'), + type: 'NON-ROLLING', + icon: "icon-bolt", + description: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.EU.description'), + selected: false, + allowed: true + }) + ], + + /** * @type {boolean} true if some request that should disable actions is in progress */ requestInProgress: false, @@ -75,7 +111,7 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage, /** * properties that stored to localStorage to resume wizard progress */ - wizardStorageProperties: ['upgradeId', 'upgradeVersion', 'currentVersion', 'isDowngrade', 'isSuspended'], + wizardStorageProperties: ['upgradeId', 'upgradeVersion', 'currentVersion', 'upgradeTypeDisplayName', 'failuresTolerance', 'isDowngrade', 'isSuspended'], /** * mutable properties of Upgrade Task @@ -472,11 +508,23 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage, this.set('upgradeId', data.resources[0].Upgrade.request_id); this.set('upgradeVersion', params.label); this.set('isDowngrade', !!params.isDowngrade); + var upgradeMethod = this.get('upgradeMethods').findProperty('type', params.type); + var upgradeTypeDisplayName = upgradeMethod ? upgradeMethod.get('displayName') : null; + this.set('upgradeTypeDisplayName', upgradeTypeDisplayName); + this.set('failuresTolerance', Em.Object.create({ + skipComponentFailures: params.skipComponentFailures, + skipSCFailures: params.skipSCFailures + })); this.setDBProperties({ upgradeVersion: params.label, upgradeId: data.resources[0].Upgrade.request_id, upgradeState: 'PENDING', - isDowngrade: !!params.isDowngrade + isDowngrade: !!params.isDowngrade, + upgradeTypeDisplayName: upgradeTypeDisplayName, + failuresTolerance: Em.Object.create({ + skipComponentFailures: params.skipComponentFailures, + skipSCFailures: params.skipSCFailures + }) }); App.set('upgradeState', 'PENDING'); App.clusterStatus.setClusterStatus({ @@ -488,21 +536,221 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage, }, /** - * upgrade confirmation popup + * success callback of updating upgrade options including failures tolerance. etc + * @param {object} data + */ + updateOptionsSuccessCallback: function (data, opt, params) { + this.set('failuresTolerance', Em.Object.create({ + skipComponentFailures: params.skipComponentFailures, + skipSCFailures: params.skipSCFailures + })); + }, + + /** + * Open upgrade options window: upgrade type and failures tolerance + * @param {boolean} isInUpgradeWizard + * @param {object} version + * @return App.ModalPopup + */ + upgradeOptions: function(isInUpgradeWizard, version) { + var self = this; + return App.ModalPopup.show({ + encodeBody: false, + primary: isInUpgradeWizard? Em.I18n.t('ok') : Em.I18n.t('common.proceed'), + primaryClass: 'btn-success', + classNames: ['upgrade-options-popup'], + header: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.header'), + bodyClass: Em.View.extend({ + templateName: require('templates/main/admin/stack_upgrade/upgrade_options'), + didInsertElement: function() { + //add pre-upgrade check results to each method object and set selected method + var view = this; + self.get('upgradeMethods').forEach(function(method){ + if (!isInUpgradeWizard && method.get('allowed')) { + self.runPreUpgradeCheckOnly.call(self, { + value: version.get('repositoryVersion'), + label: version.get('displayName'), + type: method.get('type') + }); + } + if (method.get('selected')) { + view.set('parentView.selectedMethod', method); + } + }); + App.tooltip($(".not-allowed.thumbnail"), { + placement: "bottom", + title: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.notAllowed') + }); + }, + parentView: this.get('parentView'), + isInUpgradeWizard: isInUpgradeWizard, + versionText: isInUpgradeWizard? '' : Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.bodyMsg.version').format(version.get('displayName')), + upgradeMethods: function () { + if (isInUpgradeWizard) { + self.get('upgradeMethods').forEach(function(method){ + if (method.get('displayName') == self.get('upgradeTypeDisplayName')) { + method.set('selected', true); + } else { + method.set('selected', false); + } + }); + } else { + var ruMethod = self.get('upgradeMethods').findProperty('type', 'ROLLING'); + var ssuMethod = self.get('upgradeMethods').findProperty('type', 'NON-ROLLING'); + ruMethod.set('selected', ruMethod.get('allowed')); + ssuMethod.set('selected', !ruMethod.get('allowed') && ssuMethod.get('allowed')); + } + return self.get('upgradeMethods'); + }.property('self.upgradeMethods', 'upgradeTypeDisplayName'), + selectMethod: function(event) { + if (isInUpgradeWizard || !event.context.get('allowed')) return; + var selectedMethod = event.context; + this.get('upgradeMethods').forEach(function(method){ + method.set('selected', false); + }); + selectedMethod.set('selected', true); + this.set('parentView.selectedMethod', selectedMethod); + }, + openMessage: function(event) { + if (isInUpgradeWizard || !event.context.get('allowed')) return; + var data = event.context.get('precheckResultsData'); + var header = Em.I18n.t('popup.clusterCheck.Upgrade.header').format(version.get('displayName')), + failTitle = Em.I18n.t('popup.clusterCheck.Upgrade.fail.title'), + failAlert = new Em.Handlebars.SafeString(Em.I18n.t('popup.clusterCheck.Upgrade.fail.alert')), + warningTitle = Em.I18n.t('popup.clusterCheck.Upgrade.warning.title'), + warningAlert = new Em.Handlebars.SafeString(Em.I18n.t('popup.clusterCheck.Upgrade.warning.alert')), + configsMergeWarning = data.items.findProperty('UpgradeChecks.id', "CONFIG_MERGE"), + configs = []; + if (configsMergeWarning && Em.get(configsMergeWarning, 'UpgradeChecks.status') === 'WARNING') { + data.items = data.items.rejectProperty('UpgradeChecks.id', 'CONFIG_MERGE'); + var configsMergeCheckData = Em.get(configsMergeWarning, 'UpgradeChecks.failed_detail'); + if (configsMergeCheckData) { + configs = configsMergeCheckData.map(function (item) { + var isDeprecated = Em.isNone(item.new_stack_value), + willBeRemoved = Em.isNone(item.result_value); + return { + type: item.type, + name: item.property, + currentValue: item.current, + recommendedValue: isDeprecated ? Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.deprecated') : item.new_stack_value, + isDeprecated: isDeprecated, + resultingValue: willBeRemoved ? Em.I18n.t('popup.clusterCheck.Upgrade.configsMerge.willBeRemoved') : item.result_value, + willBeRemoved: willBeRemoved + }; + }); + } + } + App.showPreUpgradeCheckPopup(data, header, failTitle, failAlert, warningTitle, warningAlert, function () { + self.runPreUpgradeCheckOnly.call(self, { + value: version.get('repositoryVersion'), + label: version.get('displayName'), + type: event.context.get('type') + }); + }, configs, version.get('displayName')); + } + }), + selectedMethod: '', + skipComponentFailures: self.get('failuresTolerance.skipComponentFailures'), + skipSCFailures: self.get('failuresTolerance.skipSCFailures'), + disablePrimary: function() { + if (isInUpgradeWizard) return false; + var selectedMethod = self.get('upgradeMethods').findProperty('selected', true); + return selectedMethod ? selectedMethod.get('precheckResultsMessageClass') == 'RED' : true; + }.property('selectedMethod', 'selectedMethod.precheckResultsMessageClass'), + onPrimary: function () { + this.hide(); + if (isInUpgradeWizard) { + return App.ajax.send({ + name: 'admin.upgrade.update.options', + sender: self, + data: { + upgradeId: self.get('upgradeId'), + skipComponentFailures: this.get('skipComponentFailures') || false, + skipSCFailures: this.get('skipSCFailures') || false + }, + success: 'updateOptionsSuccessCallback' + }); + } else { + version.upgradeType = self.get('upgradeMethods').findProperty('selected', true).get('type'); + version.upgradeTypeDisplayName = self.get('upgradeMethods').findProperty('selected', true).get('displayName'); + version.skipComponentFailures = this.get('skipComponentFailures'); + version.skipSCFailures = this.get('skipSCFailures'); + self.runPreUpgradeCheck.call(self, version); + } + }, + onSecondary: function () { + this.hide(); + }, + onClose: function () { + this.hide(); + } + }); + }, + + /** + * open upgrade options from upgrade wizard + * @return App.ModalPopup + */ + openUpgradeOptions: function () { + this.upgradeOptions(true, null); + }, + + /** + * upgrade confirmation popup including upgrade options: upgrade type and failures tolerance * @param {object} version * @return App.ModalPopup */ confirmUpgrade: function (version) { + this.upgradeOptions(false, version); + }, + + /** + * send request for pre upgrade check only + */ + runPreUpgradeCheckOnly: function(data) { + if (App.get('supports.preUpgradeCheck')) { + App.ajax.send({ + name: "admin.upgrade.pre_upgrade_check", + sender: this, + data: data, + success: "runPreUpgradeCheckOnlySuccess", + error: "runPreUpgradeCheckError" + }); + } + }, + + /** + * success callback of <code>runPreUpgradeCheckOnly()</code> + * Show a message how many fails/warnings/passed + * on clicking that message a popup window show up + * @param data {object} + * @param opt {object} + * @param params {object} + */ + runPreUpgradeCheckOnlySuccess: function (data, opt, params) { var self = this; + var message = ''; + var messageClass = 'GREEN'; + var messageIconClass = 'icon-ok'; + if (data.items.someProperty('UpgradeChecks.status', 'WARNING')) { + message = message + data.items.filterProperty('UpgradeChecks.status', 'WARNING').length + ' Warning '; + messageClass = 'ORANGE'; + messageIconClass = 'icon-warning-sign'; + } + if (data.items.someProperty('UpgradeChecks.status', 'FAIL')) { + message = data.items.filterProperty('UpgradeChecks.status', 'FAIL').length + ' Required ' + message; + messageClass = 'RED'; + messageIconClass = 'icon-remove'; + } - return App.showConfirmationPopup( - function () { - self.runPreUpgradeCheck.call(self, version); - }, - Em.I18n.t('admin.stackUpgrade.upgrade.confirm.body').format(version.get('displayName')), - null, - Em.I18n.t('admin.stackUpgrade.dialog.header').format(version.get('displayName')) - ); + if (!message) { + message = Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.preCheck.allPassed'); + } + var method = self.get('upgradeMethods').findProperty('type', params.type); + method.set('precheckResultsMessage', message); + method.set('precheckResultsMessageClass', messageClass); + method.set('precheckResultsMessageIconClass', messageIconClass); + method.set('precheckResultsData', data); }, /** @@ -512,13 +760,15 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage, runPreUpgradeCheck: function(version) { var params = { value: version.get('repositoryVersion'), - label: version.get('displayName') + label: version.get('displayName'), + type: version.get('upgradeType'), + skipComponentFailures: version.get('skipComponentFailures'), + skipSCFailures: version.get('skipSCFailures') }; - if (App.get('supports.preUpgradeCheck')) { this.set('requestInProgress', true); App.ajax.send({ - name: "admin.rolling_upgrade.pre_upgrade_check", + name: "admin.upgrade.pre_upgrade_check", sender: this, data: params, success: "runPreUpgradeCheckSuccess", @@ -587,7 +837,7 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage, }, Em.I18n.t('admin.stackUpgrade.upgrade.retry.confirm.body').format(version.get('displayName')), null, - Em.I18n.t('admin.stackUpgrade.dialog.header').format(version.get('displayName')) + Em.I18n.t('admin.stackUpgrade.dialog.header').format(version.get('upgradeTypeDislayName'), version.get('displayName')) ); }, @@ -814,6 +1064,8 @@ App.MainAdminStackAndUpgradeController = Em.Controller.extend(App.LocalStorage, upgradeState: 'INIT', upgradeVersion: undefined, currentVersion: undefined, + upgradeTypeDisplayName: undefined, + failuresTolerance: undefined, isDowngrade: undefined }); App.clusterStatus.setClusterStatus({ http://git-wip-us.apache.org/repos/asf/ambari/blob/c0451827/ambari-web/app/messages.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js index 8ac8504..c059930 100644 --- a/ambari-web/app/messages.js +++ b/ambari-web/app/messages.js @@ -269,6 +269,7 @@ Em.I18n.translations = { 'common.dataSet': 'Data Set', 'common.label': 'Label', 'common.preview': 'Preview', + 'common.options': 'Options', 'common.scope': 'Scope', 'common.clone': 'Clone', 'common.removed': 'Removed', @@ -1466,6 +1467,20 @@ Em.I18n.translations = { 'admin.stackVersions.version.downgrade.running': "Downgrade: In Process", 'admin.stackVersions.version.downgrade.aborted': "Downgrade: Aborted", + 'admin.stackVersions.version.upgrade.upgradeOptions.header': "Upgrade Options", + 'admin.stackVersions.version.upgrade.upgradeOptions.bodyMsg.version': "You are about to perform an upgrade to <b>{0}</b>.", + 'admin.stackVersions.version.upgrade.upgradeOptions.bodyMsg.method': "Please choose the method to perform this upgrade:", + 'admin.stackVersions.version.upgrade.upgradeOptions.bodyMsg.tolerance': "Please choose the tolerance with failures. (Can be modified later)", + 'admin.stackVersions.version.upgrade.upgradeOptions.tolerance.option1': "Skip all component failures", + 'admin.stackVersions.version.upgrade.upgradeOptions.tolerance.option2': "Skip all service check failures", + 'admin.stackVersions.version.upgrade.upgradeOptions.RU.title': "Rolling Upgrade", + 'admin.stackVersions.version.upgrade.upgradeOptions.RU.description': "Services remain up while the upgrade is performed. <br/>No downtime, but slower.", + 'admin.stackVersions.version.upgrade.upgradeOptions.EU.title': "Express Upgrade", + 'admin.stackVersions.version.upgrade.upgradeOptions.EU.description': "Services are shut down while the upgrade is performed. <br/>Incurs downtime, but faster.", + 'admin.stackVersions.version.upgrade.upgradeOptions.preCheck.rerun':'Rerun Checks', + 'admin.stackVersions.version.upgrade.upgradeOptions.preCheck.allPassed':'Pre-Upgrade checks passed', + 'admin.stackVersions.version.upgrade.upgradeOptions.notAllowed':'Not allowed by the current version', + 'admin.stackVersions.hosts.popup.header.current': "Current", 'admin.stackVersions.hosts.popup.header.installed': "Installed", 'admin.stackVersions.hosts.popup.header.not_installed': "Not installed", @@ -1503,7 +1518,7 @@ Em.I18n.translations = { 'admin.stackUpgrade.state.paused.downgrade': "Downgrade Paused", 'admin.stackUpgrade.state.aborted.downgrade': "Downgrade Aborted", 'admin.stackUpgrade.state.completed.downgrade': "Downgrade Finished", - 'admin.stackUpgrade.dialog.header': "Rolling Upgrade to {0}", + 'admin.stackUpgrade.dialog.header': "{0} to {1}", 'admin.stackUpgrade.dialog.downgrade.header': "Downgrade to {0}", 'admin.stackUpgrade.dialog.operationFailed': "This operation failed.", 'admin.stackUpgrade.dialog.stop': "Stop Upgrade", http://git-wip-us.apache.org/repos/asf/ambari/blob/c0451827/ambari-web/app/routes/stack_upgrade_routes.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/routes/stack_upgrade_routes.js b/ambari-web/app/routes/stack_upgrade_routes.js index 9f6034f..543831c 100644 --- a/ambari-web/app/routes/stack_upgrade_routes.js +++ b/ambari-web/app/routes/stack_upgrade_routes.js @@ -39,7 +39,7 @@ module.exports = App.WizardRoute.extend({ if (controller.get('isDowngrade')) { return Em.I18n.t('admin.stackUpgrade.dialog.downgrade.header').format(controller.get('upgradeVersion')); } else { - return Em.I18n.t('admin.stackUpgrade.dialog.header').format(controller.get('upgradeVersion')); + return Em.I18n.t('admin.stackUpgrade.dialog.header').format(controller.get('upgradeTypeDisplayName'), controller.get('upgradeVersion')); } }.property('App.router.mainAdminStackAndUpgradeController.upgradeVersion', 'App.router.mainAdminStackAndUpgradeController.isDowngrade'), bodyClass: App.upgradeWizardView, http://git-wip-us.apache.org/repos/asf/ambari/blob/c0451827/ambari-web/app/styles/stack_versions.less ---------------------------------------------------------------------- diff --git a/ambari-web/app/styles/stack_versions.less b/ambari-web/app/styles/stack_versions.less index 4ec60cb..299a912 100644 --- a/ambari-web/app/styles/stack_versions.less +++ b/ambari-web/app/styles/stack_versions.less @@ -267,6 +267,12 @@ .task-list-main-warp i { font-size: 16px; } + .upgrade-options-button { + position: absolute; + right: 10%; + top: 10px; + width: 100px; + } } .repository-list { @@ -279,6 +285,127 @@ } } +#upgrade-options-popup-content { + .method-options { + margin: 10px; + .method-option { + width: 43.5%; + } + .thumbnail { + height: 140px; + border: solid 2px white; + cursor: pointer; + width: 99%; + .method-icon { + font-size: 40px; + } + .method-name { + font-size: 16px; + font-weight: bold; + text-align: center; + margin-top: 2px; + } + .method-description { + margin-top: 5px; + text-align: center; + } + } + .ROLLING { + background-color: #d3e7ca; + .method-icon { + margin-left: 88px; + } + } + .selected.ROLLING { + border: solid 2px #a3c197; + box-shadow: 0 8px 6px -6px #91ac86; + } + .ROLLING:hover { + background-color: #c4dfb9; + } + .NON-ROLLING { + background-color: #d8e7fb; + .method-icon { + margin-left: 94px; + } + } + .selected.NON-ROLLING { + border: solid 2px #7fb2f4; + box-shadow: 0 8px 6px -6px #72a0db; + } + .NON-ROLLING:hover { + background-color: #c9defa; + } + .ROLLING.not-allowed:hover, .NON-ROLLING.not-allowed:hover { + background-color: #f3f3f3; + } + .thumbnail.not-allowed { + cursor: not-allowed; + background-color: #f3f3f3; + .method-name,.method-icon,.method-description { + color: #a9a9a9; + } + } + } + + .method-options.disabled { + .thumbnail { + cursor: not-allowed; + .method-name,.method-icon,.method-description { + color: #a9a9a9; + } + } + .ROLLING,.NON-ROLLING, + .ROLLING:hover,.NON-ROLLING:hover { + background-color: #f3f3f3; + } + .selected.ROLLING,.selected.NON-ROLLING, + .selected.ROLLING:hover,.selected.NON-ROLLING:hover { + border: solid 2px #a9a9a9; + box-shadow: 0 8px 6px -6px #a9a9a9; + } + } + + .method-precheck-message { + cursor: pointer; + text-align: center; + padding-top: 10px; + } + .method-precheck-message.GREEN { + a { + font-size: 13px; + } + .icon-ok { + color: @health-status-green; + font-size: 16px; + } + } + .method-precheck-message.RED { + a { + font-size: 13px; + } + .icon-remove { + color: #cf2a27; + font-size: 16px; + } + } + .method-precheck-message.ORANGE { + a { + font-size: 13px; + } + .icon-warning-sign { + color: @health-status-orange; + font-size: 16px; + } + } + .tolerance-text .tolerance-option { + margin: 5px 15px; + } + .text { + margin-left: 10px; + } +} + .admin-cluster { .repositories-table { margin-bottom: 10px; http://git-wip-us.apache.org/repos/asf/ambari/blob/c0451827/ambari-web/app/templates/main/admin/stack_upgrade/stack_upgrade_wizard.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/admin/stack_upgrade/stack_upgrade_wizard.hbs b/ambari-web/app/templates/main/admin/stack_upgrade/stack_upgrade_wizard.hbs index f8c4d59..ef46994 100644 --- a/ambari-web/app/templates/main/admin/stack_upgrade/stack_upgrade_wizard.hbs +++ b/ambari-web/app/templates/main/admin/stack_upgrade/stack_upgrade_wizard.hbs @@ -17,6 +17,9 @@ }} <div id="stack-upgrade-dialog"> + <button class="btn btn-primary upgrade-options-button" {{bindAttr disabled="controller.isDowngrade"}} {{action openUpgradeOptions target="controller"}}> + <i class="icon-cogs"></i> {{t common.options}} + </button> <div {{bindAttr class="view.isLoaded::hidden :row-fluid"}}> <div class="span3 task-list-main-warp">{{statusIcon controller.requestStatus}} {{view.upgradeStatusLabel}}</div> http://git-wip-us.apache.org/repos/asf/ambari/blob/c0451827/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_options.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_options.hbs b/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_options.hbs new file mode 100644 index 0000000..5902433 --- /dev/null +++ b/ambari-web/app/templates/main/admin/stack_upgrade/upgrade_options.hbs @@ -0,0 +1,49 @@ +{{! +* 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="upgrade-options-popup-content"> + <div class="text version-text">{{{view.versionText}}}</div> + <div class="text method-text">{{t admin.stackVersions.version.upgrade.upgradeOptions.bodyMsg.method}}</div> + <div {{bindAttr class=":row-fluid :method-options view.isInUpgradeWizard:disabled"}}> + {{#each method in view.upgradeMethods}} + <div class="method-option span5"> + <div {{bindAttr class="method.allowed::not-allowed method.selected:selected method.type :thumbnail"}} + {{action selectMethod method target="view"}}> + <div {{bindAttr class="method.icon :method-icon"}}></div> + <div class="method-name">{{method.displayName}}</div> + <div class="method-description">{{{method.description}}}</div> + </div> + {{#unless view.isInUpgradeWizard}} + <div {{bindAttr class=":method-precheck-message method.precheckResultsMessageClass"}}> + <i {{bindAttr class="method.precheckResultsMessageIconClass"}}></i> + <a {{action openMessage method target="view"}}> + {{method.precheckResultsMessage}} + </a> + </div> + {{/unless}} + </div> + {{/each}} + </div> + + <div class="text tolerance-text">{{t admin.stackVersions.version.upgrade.upgradeOptions.bodyMsg.tolerance}} + <div class="tolerance-option">{{view Ember.Checkbox checkedBinding="view.parentView.skipComponentFailures"}} + {{t admin.stackVersions.version.upgrade.upgradeOptions.tolerance.option1}}</div> + <div class="tolerance-option">{{view Ember.Checkbox checkedBinding="view.parentView.skipSCFailures"}} + {{t admin.stackVersions.version.upgrade.upgradeOptions.tolerance.option2}}</div> + </div> +</div> http://git-wip-us.apache.org/repos/asf/ambari/blob/c0451827/ambari-web/app/utils/ajax/ajax.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js index 075eb9a..5768e15 100644 --- a/ambari-web/app/utils/ajax/ajax.js +++ b/ambari-web/app/utils/ajax/ajax.js @@ -1573,6 +1573,21 @@ var urls = { 'admin.upgrade.service_checks': { 'real': '/clusters/{clusterName}/upgrades/{upgradeId}/upgrade_groups?upgrade_items/UpgradeItem/status=COMPLETED&upgrade_items/tasks/Tasks/status.in(FAILED,ABORTED,TIMEDOUT)&upgrade_items/tasks/Tasks/command=SERVICE_CHECK&fields=upgrade_items/tasks/Tasks/command_detail,upgrade_items/tasks/Tasks/status&minimal_response=true' }, + 'admin.upgrade.update.options': { + 'real': '/clusters/{clusterName}/upgrades/{upgradeId}', + 'mock': '/data/stack_versions/start_upgrade.json', + 'type': 'PUT', + 'format': function (data) { + return { + data: JSON.stringify({ + "Upgrade": { + "skip_failures": data.skipComponentFailures, + "skip_service_check_failures": data.skipSCFailures + } + }) + } + } + }, 'admin.upgrade.start': { 'real': '/clusters/{clusterName}/upgrades', 'mock': '/data/stack_versions/start_upgrade.json', @@ -1581,7 +1596,10 @@ var urls = { return { data: JSON.stringify({ "Upgrade": { - "repository_version": data.value + "repository_version": data.value, + "type": data.type, + "skip_failures": data.skipComponentFailures, + "skip_service_check_failures": data.skipSCFailures } }) } @@ -1689,8 +1707,8 @@ var urls = { } }, - 'admin.rolling_upgrade.pre_upgrade_check': { - 'real': '/clusters/{clusterName}/rolling_upgrades_check?fields=*&UpgradeChecks/repository_version={value}', + 'admin.upgrade.pre_upgrade_check': { + 'real': '/clusters/{clusterName}/rolling_upgrades_check?fields=*&UpgradeChecks/repository_version={value}&UpgradeChecks/upgrade_type={type}', 'mock': '/data/stack_versions/pre_upgrade_check.json' }, http://git-wip-us.apache.org/repos/asf/ambari/blob/c0451827/ambari-web/app/views/common/modal_popups/cluster_check_popup.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/modal_popups/cluster_check_popup.js b/ambari-web/app/views/common/modal_popups/cluster_check_popup.js index 6e99102..6e901ec 100644 --- a/ambari-web/app/views/common/modal_popups/cluster_check_popup.js +++ b/ambari-web/app/views/common/modal_popups/cluster_check_popup.js @@ -71,3 +71,58 @@ App.showClusterCheckPopup = function (data, header, failTitle, failAlert, warnin } }); }; + + +/** + * popup to display requirements that are not met + * for current action + * @param data + * @param header + * @param failTitle + * @param failAlert + * @param warningTitle + * @param warningAlert + * @param callback + * @param configs + * @param upgradeVersion + * @returns {*|void} + */ +App.showPreUpgradeCheckPopup = function (data, header, failTitle, failAlert, warningTitle, warningAlert, callback, configs, upgradeVersion) { + var fails = data.items.filterProperty('UpgradeChecks.status', 'FAIL'), + warnings = data.items.filterProperty('UpgradeChecks.status', 'WARNING'), + hasConfigsMergeConflicts = !!(configs && configs.length), + popupBody = { + failTitle: failTitle, + failAlert: failAlert, + warningTitle: warningTitle, + warningAlert: warningAlert, + templateName: require('templates/common/modal_popups/cluster_check_dialog'), + fails: fails, + warnings: warnings, + hasConfigsMergeConflicts: hasConfigsMergeConflicts + }; + if (hasConfigsMergeConflicts) { + popupBody.configsMergeTable = Em.View.extend({ + templateName: require('templates/main/admin/stack_upgrade/upgrade_configs_merge_table'), + configs: configs, + didInsertElement: function () { + App.tooltip($('.recommended-value'), { + title: upgradeVersion + }); + } + }); + } + return App.ModalPopup.show({ + primary: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.preCheck.rerun'), + secondary: Em.I18n.t('common.cancel'), + header: header, + classNames: ['cluster-check-popup'], + bodyClass: Em.View.extend(popupBody), + onPrimary: function () { + this._super(); + if (callback) { + callback(); + } + } + }); +}; http://git-wip-us.apache.org/repos/asf/ambari/blob/c0451827/ambari-web/test/controllers/main/admin/stack_and_upgrade_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/admin/stack_and_upgrade_controller_test.js b/ambari-web/test/controllers/main/admin/stack_and_upgrade_controller_test.js index b034ac4..ce176ea 100644 --- a/ambari-web/test/controllers/main/admin/stack_and_upgrade_controller_test.js +++ b/ambari-web/test/controllers/main/admin/stack_and_upgrade_controller_test.js @@ -299,14 +299,20 @@ describe('App.MainAdminStackAndUpgradeController', function() { it("make ajax call", function() { controller.runPreUpgradeCheck(Em.Object.create({ repositoryVersion: '2.2', - displayName: 'HDP-2.2' + displayName: 'HDP-2.2', + upgradeType: 'ROLLING', + skipComponentFailures: false, + skipSCFailures: false })); expect(App.ajax.send.getCall(0).args[0]).to.eql({ - name: "admin.rolling_upgrade.pre_upgrade_check", + name: "admin.upgrade.pre_upgrade_check", sender: controller, data: { value: '2.2', - label: 'HDP-2.2' + label: 'HDP-2.2', + type: 'ROLLING', + skipComponentFailures: false, + skipSCFailures: false }, success: "runPreUpgradeCheckSuccess", error: "runPreUpgradeCheckError" @@ -520,6 +526,16 @@ describe('App.MainAdminStackAndUpgradeController', function() { } ] }; + controller.upgradeMethods = [ + Em.Object.create({ + displayName: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.RU.title'), + type: 'ROLLING' + }), + Em.Object.create({ + displayName: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.EU.title'), + type: 'NON-ROLLING' + }) + ]; controller.upgradeSuccessCallback(data, {}, {label: 'HDP-2.2.1', isDowngrade: true}); expect(controller.load.calledOnce).to.be.true; expect(controller.get('upgradeVersion')).to.equal('HDP-2.2.1'); @@ -748,24 +764,56 @@ describe('App.MainAdminStackAndUpgradeController', function() { }); }); - describe("#confirmUpgrade()", function() { + describe("#upgradeOptions()", function() { before(function () { - sinon.spy(App, 'showConfirmationPopup'); + sinon.spy(App, 'ModalPopup'); sinon.stub(controller, 'runPreUpgradeCheck', Em.K); }); after(function () { - App.showConfirmationPopup.restore(); + App.ModalPopup.restore(); controller.runPreUpgradeCheck.restore(); }); it("show confirmation popup", function() { var version = Em.Object.create({displayName: 'HDP-2.2'}); - var popup = controller.confirmUpgrade(version); - expect(App.showConfirmationPopup.calledOnce).to.be.true; + controller.upgradeMethods = [ + Em.Object.create({ + displayName: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.RU.title'), + type: 'ROLLING', + icon: "icon-dashboard", + description: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.RU.description'), + selected: true, + allowed: true + }), + Em.Object.create({ + displayName: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.EU.title'), + type: 'NON-ROLLING', + icon: "icon-bolt", + description: Em.I18n.t('admin.stackVersions.version.upgrade.upgradeOptions.EU.description'), + selected: false, + allowed: true + }) + ]; + var popup = controller.upgradeOptions(false, version); + expect(App.ModalPopup.calledOnce).to.be.true; popup.onPrimary(); expect(controller.runPreUpgradeCheck.calledWith(version)).to.be.true; }); }); + describe("#confirmUpgrade()", function() { + before(function () { + sinon.stub(controller, 'upgradeOptions', Em.K); + }); + after(function () { + controller.upgradeOptions.restore(); + }); + it("show show upgrade options popup window", function() { + var version = Em.Object.create({displayName: 'HDP-2.2'}); + controller.confirmUpgrade(version); + expect(controller.upgradeOptions.calledWith(false, version)).to.be.true; + }); + }); + describe("#downgrade()", function() { before(function () { sinon.stub(App.ajax, 'send', Em.K);
