This is an automated email from the ASF dual-hosted git repository. ishanbha pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/trunk by this push: new 6ea9747 [AMBARI-24803] Separating Restart All, Masters and Slaves. 6ea9747 is described below commit 6ea9747908c20d9fcdbacbc7151fbbf4d1788683 Author: Ishan Bhatt <ishanbhatt.1...@gmail.com> AuthorDate: Thu Oct 18 05:59:46 2018 -0700 [AMBARI-24803] Separating Restart All, Masters and Slaves. --- ambari-web/app/controllers/main/service/item.js | 58 +++++++++--- ambari-web/app/messages.js | 2 +- ambari-web/app/models/host_component.js | 6 +- .../app/templates/common/service_restart.hbs | 60 ++++++------ ambari-web/app/utils/batch_scheduled_requests.js | 101 ++++++++++++++------- .../app/views/common/service_restart_view.js | 2 + 6 files changed, 151 insertions(+), 78 deletions(-) diff --git a/ambari-web/app/controllers/main/service/item.js b/ambari-web/app/controllers/main/service/item.js index d615548..a900edb 100644 --- a/ambari-web/app/controllers/main/service/item.js +++ b/ambari-web/app/controllers/main/service/item.js @@ -966,16 +966,49 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow } }, - chooseAndRestartHostComponents: function () { - let serviceName = this.get('content.serviceName'); - const mastersForRestart = serviceName === 'HDFS' ? this.getMastersForHdfsRestart(): this.getMastersForRestart(serviceName); - batchUtils.showServiceRestartPopup(serviceName, mastersForRestart); + restartServiceAllComponents: function () { + batchUtils.showServiceRestartPopup(this.get('content.serviceName'), this.getMastersForRestart.bind(this), this.getSlavesForRestart.bind(this)); }, + restartServiceMastersOnly: function () { + batchUtils.showServiceRestartPopup(this.get('content.serviceName'), this.getMastersForRestart.bind(this)); + }, + + restartServiceSlavesOnly: function () { + batchUtils.showServiceRestartPopup(this.get('content.serviceName'), null, this.getSlavesForRestart.bind(this)); + }, + + restartOptions: [ + Em.Object.create({ + action: 'restartServiceAllComponents', + context: { + label: 'Restart All', + name: 'RESTART_ALL' + } + }), + Em.Object.create({ + action: 'restartServiceMastersOnly', + context: { + label: 'Restart Masters', + name: 'RESTART_MASTERS' + } + }), + Em.Object.create({ + action: 'restartServiceSlavesOnly', + context: { + label: 'Restart Slaves', + name: 'RESTART_SLAVES' + } + }), + ], getMastersForRestart: function (serviceName) { - return this.get('content.hostComponents').filter((component) =>{ - return component.get('service.serviceName') === serviceName && component.get('isMaster'); - }); + if (serviceName === 'HDFS') { + return this.getMastersForHdfsRestart(); + } else { + return this.get('content.hostComponents').filter((component) => { + return component.get('service.serviceName') === serviceName && component.get('isMaster'); + }); + } }, getMastersForHdfsRestart: function () { @@ -1020,11 +1053,7 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow }); } } else { - //Add SNamenode - if (!standbyNameNodes.length > 0 && hdfsService.get('snameNode')) { - hostCompOrdered.push(hdfsService.get('snameNode')); - } const sNameNode = hdfsService.get('snameNode') || App.HostComponent.find().findProperty('componentName', 'SECONDARY_NAMENODE') if (sNameNode) hostCompOrdered.push(sNameNode); @@ -1035,6 +1064,13 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow return hostCompOrdered; }, + getSlavesForRestart: function (serviceName) { + return this.get('content.hostComponents').filter((component) => { + return component.get('service.serviceName') === serviceName && component.get('isSlave'); + }); + }, + + restartCertainHostComponents: function (context) { const serviceDisplayName = this.get('content.displayName'), {components, hosts, label, serviceName} = context; diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js index 67c45f3..e93c508 100644 --- a/ambari-web/app/messages.js +++ b/ambari-web/app/messages.js @@ -3284,7 +3284,7 @@ Em.I18n.translations = { 'service.rolling.restart.choose.info': 'Critical services remain running while the upgrade is performed. </br>Minimized disruption, but is a slower upgrade.', 'service.express.restart.choose.info': 'Services are stopped when this upgrade is performed. </br>Incurs downtime, but is a faster upgrade.', 'service.restart.show.advanced.info': 'Show advanced configurations options <p style="font-size: 12px; color: #999999; display: inline;">(Restart by batches/hosts, interval between restarts, etc.)</p>', - 'service.restart.rolling.title.info': 'RESTART HOSTS BY', + 'service.restart.rolling.restart.hosts.by': 'RESTART HOSTS BY', 'service.restart.rolling.batchesOfHosts': 'Batches of Hosts', 'service.restart.rolling.rackByRack': 'Rack by Rack', 'service.restart.rolling.advanced.noOfHosts': 'NUMBER OF HOSTS IN A BATCH', diff --git a/ambari-web/app/models/host_component.js b/ambari-web/app/models/host_component.js index c5d3090..92014ba 100644 --- a/ambari-web/app/models/host_component.js +++ b/ambari-web/app/models/host_component.js @@ -358,11 +358,13 @@ App.HostComponentActionMap = { }, //Ongoing feature. Will later replace RESTART_ALL RESTART_SERVICE: { - action: 'chooseAndRestartHostComponents', + action: 'restartServiceAllComponents', context: ctx.get('serviceName'), label: Em.I18n.t('restart.service.rest.context').format(ctx.get('displayName')), cssClass: 'glyphicon glyphicon-time', - disabled: false + disabled: false, + hasSubmenu: true, + submenuOptions: ctx.get('controller.restartOptions') }, RESTART_NAMENODES: { action: '', diff --git a/ambari-web/app/templates/common/service_restart.hbs b/ambari-web/app/templates/common/service_restart.hbs index 226b9df..7fe817c 100644 --- a/ambari-web/app/templates/common/service_restart.hbs +++ b/ambari-web/app/templates/common/service_restart.hbs @@ -39,37 +39,39 @@ </div> {{#if view.showAdvancedOptions}} <div class="rolling-restart-advanced"> - {{t service.restart.rolling.title.info}} - <div class="rolling-restart-by"> - <div class="radio big-radio"> - {{view view.batchesOfHostsRadioButton labelIdentifier="use-batches-of-hosts"}} - <i class="fa fa-question-circle"></i> - </div> - <div class="radio big-radio"> - {{view view.rackByRackRadioButton labelIdentifier="use-rack-by-rack"}} - <i class="fa fa-question-circle"></i> - </div> - </div> - {{#if view.batchesOfHosts}} - <div class="input-option row"> - <div>{{t service.restart.rolling.advanced.noOfHosts}}</div> - {{view Ember.TextField type="number" class="input-sm col-xs-2" valueBinding="view.noOfHostsInBatch"}}<br> - </div> - <div class=" input-option row"> - <div>{{t service.restart.rolling.advanced.batchIntervalHosts}}</div> - {{view Ember.TextField type="number" class="input-sm col-xs-2" valueBinding="view.batchIntervalHosts"}} - </div> - {{else}} - <div class="input-option row"> - <div>{{t service.restart.rolling.advanced.percentRacks}}</div> - {{view Ember.TextField type="number" class="input-sm col-xs-2" valueBinding="view.percentRackStarted"}}<br> - </div> - <div class="input-option row"> - <div>{{t service.restart.rolling.advanced.batchIntervalRacks}}</div> - {{view Ember.TextField type="number" class="input-sm col-xs-2" valueBinding="view.batchIntervalRacks"}} + {{#if view.showBatchRackOptions}} + {{t service.restart.rolling.restart.hosts.by}} + <div class="rolling-restart-by"> + <div class="radio big-radio"> + {{view view.batchesOfHostsRadioButton labelIdentifier="use-batches-of-hosts"}} + <i class="fa fa-question-circle"></i> + </div> + <div class="radio big-radio"> + {{view view.rackByRackRadioButton labelIdentifier="use-rack-by-rack"}} + <i class="fa fa-question-circle"></i> + </div> </div> + {{#if view.batchesOfHosts}} + <div class="input-option row"> + <div>{{t service.restart.rolling.advanced.noOfHosts}}</div> + {{view Ember.TextField type="number" class="input-sm col-xs-2" valueBinding="view.noOfHostsInBatch"}}<br> + </div> + <div class=" input-option row"> + <div>{{t service.restart.rolling.advanced.batchIntervalHosts}}</div> + {{view Ember.TextField type="number" class="input-sm col-xs-2" valueBinding="view.batchIntervalHosts"}} + </div> + {{else}} + <div class="input-option row"> + <div>{{t service.restart.rolling.advanced.percentRacks}}</div> + {{view Ember.TextField type="number" class="input-sm col-xs-2" valueBinding="view.percentRackStarted"}}<br> + </div> + <div class="input-option row"> + <div>{{t service.restart.rolling.advanced.batchIntervalRacks}}</div> + {{view Ember.TextField type="number" class="input-sm col-xs-2" valueBinding="view.batchIntervalRacks"}} + </div> + {{/if}} + <hr class="separator"> {{/if}} - <hr class="separator"> <div style="margin-top: 20px;"> {{view App.CheckboxView checkedBinding="view.isRetryChecked" labelTranslate="service.restart.rolling.advanced.automatic.retry"}} </div> diff --git a/ambari-web/app/utils/batch_scheduled_requests.js b/ambari-web/app/utils/batch_scheduled_requests.js index 1ab73df..f9948eb 100644 --- a/ambari-web/app/utils/batch_scheduled_requests.js +++ b/ambari-web/app/utils/batch_scheduled_requests.js @@ -499,60 +499,91 @@ module.exports = { }); }, - - showServiceRestartPopup: function (serviceName, masterComponents, slaveComponents) { + /** + * Service rolling restart popup + * @param {String} serviceName: name of the service that should be restarted + * @param {function} mastersForRestart: Callback function to retrieve master components for restart + * @param {function} workersForRestart: Callback function to retrieve worker components for restart + */ + showServiceRestartPopup: function (serviceName, mastersForRestart, workersForRestart) { let self = this; + const isRestartAll = !!(mastersForRestart && workersForRestart); + const isMastersOnly = !!(mastersForRestart && !workersForRestart); + const isSlavesOnly = !!(!mastersForRestart && workersForRestart); App.ModalPopup.show({ header: Em.I18n.t('common.configure.restart'), bodyClass: App.ServiceRestartView.extend({ - serviceName: serviceName + isRestartAll, isMastersOnly, isSlavesOnly }), primary: Em.I18n.t('common.restart'), primaryClass: 'btn-warning', classNames: ['common-modal-wrapper'], modalDialogClasses: ['modal-lg'], onPrimary: function () { - let batches = []; - for (let i=0; i<masterComponents.length; i++) { - const hostName = masterComponents[i].get('hostName'); - const component = masterComponents[i].get('componentName'); - const context = "RESTART " + masterComponents[i].get('displayName'); - batches.push({ - "order_id": i+1, - "type": 'POST', - "uri": "/clusters/" + App.get('clusterName') + "/requests/", - "RequestBodyInfo": { - "RequestInfo": { - "command": "RESTART", - "context": context, - }, - "Requests/resource_filters": [{ - "service_name": serviceName, - "component_name": component, - "hosts": hostName - }] - } - }) + let isRollingRestart = this.get('innerView.useRolling'); + if (isRollingRestart) { + //TODO introduce masters and workers logic + const masters = mastersForRestart(serviceName); + self.rollingRestartRequest(masters, serviceName); + } else { + const query = Em.Object.create({status: 'INIT'}); + const serviceDisplayName = App.Service.find().findProperty('serviceName', serviceName).get('displayName'); + self.restartAllServiceHostComponents(serviceDisplayName, serviceName, false, query, false); } - App.ajax.send({ - name: 'common.batch.request_schedules', - sender: self, - data: { - intervalTimeSeconds: 1, - tolerateSize: 0, - batches: batches - }, - success: 'serviceRestartSuccess', - showLoadingPopup: true - }); this._super(); } }) + }, + /** + * Creates batches and send rolling restart request. + * TODO modify this to include request to restart workers. + * @param {App.hostComponent[]} [hostComponents] list of hostComponents that should be restarted + * @param {String} serviceName: Name of the service to be restarted. + */ + + rollingRestartRequest: function (hostComponents, serviceName) { + let batches = []; + for (let i=0; i<hostComponents.length; i++) { + const hostName = hostComponents[i].get('hostName'); + const component = hostComponents[i].get('componentName'); + const context = "RESTART " + hostComponents[i].get('displayName'); + batches.push({ + "order_id": i+1, + "type": 'POST', + "uri": "/clusters/" + App.get('clusterName') + "/requests/", + "RequestBodyInfo": { + "RequestInfo": { + "command": "RESTART", + "context": context, + }, + "Requests/resource_filters": [{ + "service_name": serviceName, + "component_name": component, + "hosts": hostName + }] + } + }) + } + App.ajax.send({ + name: 'common.batch.request_schedules', + sender: this, + data: { + intervalTimeSeconds: 1, + tolerateSize: 0, + batches: batches + }, + success: 'serviceRestartSuccess', + showLoadingPopup: true + }); }, + /** + * Callback function for rollingRestartRequest that shows BG Modal if restart request sent successfully + * TODO replace it with a progress view that shows rolling restart tasks + */ serviceRestartSuccess: function (data) { if (data && (data.Requests || data.resources[0].RequestSchedule)) { App.router.get('userSettingsController').dataLoading('show_bg').done(function (initValue) { diff --git a/ambari-web/app/views/common/service_restart_view.js b/ambari-web/app/views/common/service_restart_view.js index 1351751..e9beb82 100644 --- a/ambari-web/app/views/common/service_restart_view.js +++ b/ambari-web/app/views/common/service_restart_view.js @@ -22,12 +22,14 @@ App.ServiceRestartView = Em.View.extend({ templateName: require('templates/common/service_restart'), didInsertElement: function() { + this.set('parentView.innerView', this); this.initDefaultConfigs(); }, initDefaultConfigs: function () { this.set('useRolling', true); this.set('showAdvancedOptions', false); + this.set('showBatchRackOptions', this.get('isRestartAll') || this.get('isSlavesOnly')); this.set('batchesOfHosts', true); this.set('noOfHostsInBatch', 10); this.set('batchIntervalHosts', 120);