123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441 |
- /**
- * 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 stringUtils = require('utils/string_utils');
- App.upgradeWizardView = Em.View.extend({
- controllerBinding: 'App.router.mainAdminStackAndUpgradeController',
- templateName: require('templates/main/admin/stack_upgrade/stack_upgrade_wizard'),
- /**
- * @type {Array}
- */
- failedStatuses: ['HOLDING_FAILED', 'HOLDING_TIMEDOUT', 'FAILED', 'TIMED_OUT'],
- /**
- * @type {Array}
- */
- activeStatuses: ['HOLDING_FAILED', 'HOLDING_TIMEDOUT', 'FAILED', 'TIMED_OUT', 'HOLDING', 'IN_PROGRESS'],
- /**
- * update timer
- * @type {number|null}
- * @default null
- */
- updateTimer: null,
- /**
- * update timer of Upgrade Item
- * @type {number|null}
- * @default null
- */
- upgradeItemTimer: null,
- /**
- * @type {boolean}
- */
- isLoaded: false,
- /**
- * @type {boolean}
- */
- isDetailsOpened: false,
- /**
- * @type {boolean}
- */
- outsideView: true,
- /**
- * Downgrade should be available only if target version higher than current, so we can't downgrade
- * when downgrade already started
- * @type {boolean}
- */
- isDowngradeAvailable: Em.computed.and('!controller.isDowngrade', 'controller.downgradeAllowed'),
- /**
- * progress value is rounded to floor
- * @type {number}
- */
- overallProgress: function () {
- return Math.floor(this.get('controller.upgradeData.Upgrade.progress_percent'));
- }.property('controller.upgradeData.Upgrade.progress_percent'),
- /**
- * upgrade groups, reversed and PENDING ones are hidden
- * @type {Array}
- */
- upgradeGroups: function () {
- return this.get('controller.upgradeData.upgradeGroups') || [];
- }.property('controller.upgradeData.upgradeGroups'),
- /**
- * currently active group
- * @type {object|undefined}
- */
- activeGroup: function () {
- return this.get('upgradeGroups').find(function (item) {
- return this.get('activeStatuses').contains(item.get('status'));
- }, this);
- }.property('upgradeGroups.@each.status'),
- /**
- * if upgrade group is in progress it should have currently running item
- * @type {object|undefined}
- */
- runningItem: Em.computed.findBy('activeGroup.upgradeItems', 'status', 'IN_PROGRESS'),
- /**
- * if upgrade group is failed it should have failed item
- * @type {object|undefined}
- */
- failedItem: function () {
- return this.get('activeGroup.upgradeItems') && this.get('activeGroup.upgradeItems').find(function (item) {
- return this.get('failedStatuses').contains(item.get('status'));
- }, this);
- }.property('activeGroup.upgradeItems.@each.status'),
- /**
- * upgrade doesn't have any failed or manual or running item
- * @type {boolean}
- */
- noActiveItem: function () {
- return (Em.isNone(this.get('failedItem')) && Em.isNone(this.get('runningItem')) && Em.isNone(this.get('manualItem'))) &&
- !['INIT', 'COMPLETED', 'ABORTED'].contains(App.get('upgradeState'));
- }.property('failedItem', 'runningItem', 'manualItem', 'App.upgradeState'),
- /**
- * details of currently active task
- * @type {object|null}
- */
- taskDetails: function () {
- if (this.get('runningItem')) {
- return this.get('runningItem').get('tasks').findProperty('status', 'IN_PROGRESS');
- } else if (this.get('failedItem')) {
- return this.get('failedItem').get('tasks').find(function (task) {
- return this.get('failedStatuses').contains(task.get('status'));
- }, this);
- } else {
- return null;
- }
- }.property('failedItem.tasks.@each.status', 'runningItem.tasks.@each.status'),
- /**
- * indicate whether failed item can be skipped or retried in order to continue Upgrade
- * @type {boolean}
- */
- isHoldingState: function () {
- return Boolean(this.get('failedItem.status') && this.get('failedItem.status').contains('HOLDING'));
- }.property('failedItem.status'),
- /**
- * @type {boolean}
- */
- isManualDone: false,
- /**
- * if manualItem has been switched then isManualDone flag should be reset
- */
- resetManualDone: function() {
- this.set('isManualDone', false);
- }.observes('manualItem'),
- /**
- * @type {boolean}
- */
- isManualProceedDisabled: Em.computed.or('!isManualDone', 'controller.requestInProgress'),
- /**
- * if upgrade group is manual it should have manual item
- * @type {object|undefined}
- */
- manualItem: Em.computed.findBy('activeGroup.upgradeItems', 'status', 'HOLDING'),
- /**
- * plain manual item
- * @type {object|undefined}
- */
- plainManualItem: function () {
- return this.get('manualItem') && ![
- this.get('controller.finalizeContext'),
- this.get("controller.slaveFailuresContext"),
- this.get("controller.serviceCheckFailuresContext")
- ].contains(this.get('manualItem.context'));
- }.property('manualItem.context'),
- /**
- * manualItem: indicate whether the step is "Slave component failures", a dialog with instructions will show up for manual steps
- * @type {boolean}
- */
- isSlaveComponentFailuresItem: function () {
- var item = this.get('activeGroup.upgradeItems') && this.get('activeGroup.upgradeItems').findProperty('context', this.get("controller.slaveFailuresContext"));
- return item && ['HOLDING', 'HOLDING_FAILED'].contains(item.get('status'));
- }.property('activeGroup.upgradeItems.@each.status', 'activeGroup.upgradeItems.@each.context'),
- /**
- * manualItem: indicate whether the step is "Service check failures", a dialog with instructions will show up for manual steps
- * @type {boolean}
- */
- isServiceCheckFailuresItem: Em.computed.equalProperties('manualItem.context', 'controller.serviceCheckFailuresContext'),
- /**
- * manualItem: indicate whether the step is Finalize
- * @type {boolean}
- */
- isFinalizeItem: Em.computed.equalProperties('manualItem.context', 'controller.finalizeContext'),
- /**
- * label of Upgrade status
- * @type {string}
- */
- upgradeStatusLabel: function() {
- var labelKey = null;
- switch (this.get('controller.upgradeData.Upgrade.request_status')) {
- case 'QUEUED':
- case 'PENDING':
- case 'IN_PROGRESS':
- labelKey = 'admin.stackUpgrade.state.inProgress';
- break;
- case 'COMPLETED':
- labelKey = 'admin.stackUpgrade.state.completed';
- break;
- case 'ABORTED':
- if (this.get('controller.isSuspended')) {
- labelKey = 'admin.stackUpgrade.state.paused';
- } else {
- labelKey = 'admin.stackUpgrade.state.aborted';
- }
- break;
- case 'TIMEDOUT':
- case 'FAILED':
- case 'HOLDING_FAILED':
- case 'HOLDING_TIMEDOUT':
- case 'HOLDING':
- labelKey = 'admin.stackUpgrade.state.paused';
- break;
- }
- if (labelKey) {
- labelKey += (this.get('controller.isDowngrade')) ? '.downgrade' : "";
- return Em.I18n.t(labelKey);
- } else {
- return "";
- }
- }.property('controller.upgradeData.Upgrade.request_status', 'controller.isDowngrade', 'controller.isSuspended'),
- /**
- * toggle details box
- */
- toggleDetails: function () {
- this.toggleProperty('isDetailsOpened');
- },
- /**
- * close details block if no active task present
- */
- closeDetails: function () {
- if (this.get('noActiveItem')) {
- this.set('isDetailsOpened', false);
- }
- }.observes('noActiveItem'),
- /**
- * start polling upgrade data
- */
- startPolling: function () {
- var self = this;
- if (App.get('clusterName')) {
- this.get('controller').loadUpgradeData().done(function () {
- self.set('isLoaded', true);
- self.doPolling();
- });
- }
- }.observes('App.clusterName'),
- getSkippedServiceChecks: function () {
- if (this.get('isFinalizeItem')) {
- if (!this.get('controller.areSkippedServiceChecksLoaded')) {
- var self = this;
- App.ajax.send({
- name: 'admin.upgrade.service_checks',
- sender: this,
- data: {
- upgradeId: this.get('controller.upgradeId')
- },
- success: 'getSkippedServiceChecksSuccessCallback'
- }).complete(function () {
- self.set('controller.areSkippedServiceChecksLoaded', true);
- });
- }
- } else {
- this.set('controller.areSkippedServiceChecksLoaded', false);
- }
- }.observes('isFinalizeItem'),
- getSkippedServiceChecksSuccessCallback: function (data) {
- if (data.items && data.items.length) {
- var lastItemWithChecks = data.items[data.items.length - 1];
- if (lastItemWithChecks && lastItemWithChecks.upgrade_items && lastItemWithChecks.upgrade_items.length) {
- var skippedServiceChecks = [];
- lastItemWithChecks.upgrade_items.forEach(function (item) {
- if (item.tasks && item.tasks.length) {
- item.tasks.forEach(function (task) {
- var detail = Em.get(task, 'Tasks.command_detail');
- if (detail && detail.startsWith('SERVICE_CHECK ')) {
- skippedServiceChecks.push(App.format.role(detail.replace('SERVICE_CHECK ', '')));
- }
- });
- }
- });
- skippedServiceChecks = skippedServiceChecks.uniq();
- this.set('controller.skippedServiceChecks', skippedServiceChecks);
- }
- }
- },
- /**
- * get slave-component failure hosts
- */
- getSlaveComponentItem: function() {
- var controller = this.get('controller');
- if (this.get('isSlaveComponentFailuresItem')) {
- if (!this.get('controller.areSlaveComponentFailuresHostsLoaded')) {
- var item = this.get('activeGroup.upgradeItems') && this.get('activeGroup.upgradeItems').findProperty('context', this.get("controller.slaveFailuresContext"));
- controller.getUpgradeItem(item, 'getSlaveComponentItemSuccessCallback').complete(function () {
- controller.set('areSlaveComponentFailuresHostsLoaded', true);
- });
- }
- } else {
- controller.set('areSlaveComponentFailuresHostsLoaded', false);
- }
- }.observes('isSlaveComponentFailuresItem'),
- /**
- * get service names of Service Check failures
- */
- getServiceCheckItem: function() {
- var controller = this.get('controller');
- if (this.get('isServiceCheckFailuresItem')) {
- if (!this.get('controller.areServiceCheckFailuresServicenamesLoaded')) {
- controller.getUpgradeItem(this.get('manualItem'), 'getServiceCheckItemSuccessCallback').complete(function () {
- controller.set('areServiceCheckFailuresServicenamesLoaded', true);
- });
- }
- } else {
- controller.set('areServiceCheckFailuresServicenamesLoaded', false);
- }
- }.observes('isServiceCheckFailuresItem'),
- /**
- * start polling upgrade data
- */
- willInsertElement: function () {
- this.startPolling();
- },
- /**
- * stop polling upgrade data
- */
- willDestroyElement: function () {
- clearTimeout(this.get('updateTimer'));
- clearTimeout(this.get('upgradeItemTimer'));
- this.set('isLoaded', false);
- },
- /**
- * load upgrade data with time interval
- */
- doPolling: function () {
- var self = this;
- this.set('updateTimer', setTimeout(function () {
- self.get('controller').loadUpgradeData().done(function() {
- self.doPolling();
- });
- }, App.bgOperationsUpdateInterval));
- },
- /**
- * poll for tasks when item is expanded
- */
- doUpgradeItemPolling: function () {
- var self = this;
- var item = this.get('runningItem') || this.get('failedItem');
- if (item && this.get('isDetailsOpened')) {
- this.get('controller').getUpgradeItem(item).complete(function () {
- self.set('upgradeItemTimer', setTimeout(function () {
- self.doUpgradeItemPolling();
- }, App.bgOperationsUpdateInterval));
- });
- } else {
- clearTimeout(this.get('upgradeItemTimer'));
- }
- }.observes('isDetailsOpened'),
- /**
- * set current upgrade item state to FAILED (for HOLDING_FAILED) or TIMED_OUT (for HOLDING_TIMED_OUT)
- * in order to ignore fail and continue Upgrade
- * @param {object} event
- */
- continue: function (event) {
- this.get('controller').setUpgradeItemStatus(event.context, event.context.get('status').slice(8));
- this.set('isDetailsOpened', false);
- },
- /**
- * set current upgrade item state to PENDING in order to retry Upgrade
- * @param {object} event
- */
- retry: function (event) {
- this.get('controller').setUpgradeItemStatus(event.context, 'PENDING');
- this.set('isDetailsOpened', false);
- },
- /**
- * set current upgrade item state to COMPLETED in order to proceed
- * @param {object} event
- */
- complete: function (event) {
- this.get('controller').setUpgradeItemStatus(event.context, 'COMPLETED');
- this.set('isManualDone', false);
- },
- pauseUpgrade: function() {
- this.get('controller').suspendUpgrade();
- this.get('parentView').closeWizard();
- },
- /**
- * @type {string}
- */
- failedHostsMessage: function() {
- var count = this.get('controller.slaveComponentStructuredInfo.hosts.length') || 0;
- return Em.I18n.t('admin.stackUpgrade.failedHosts.showHosts').format(count);
- }.property('controller.slaveComponentStructuredInfo.hosts'),
- showFailedHosts: function() {
- return App.ModalPopup.show({
- header: Em.I18n.t('admin.stackUpgrade.failedHosts.header'),
- bodyClass: App.FailedHostsPopupBodyView,
- secondary: null,
- primary: Em.I18n.t('common.close'),
- content: this.get('controller.slaveComponentStructuredInfo')
- });
- }
- });
|