AMBARI-18377. Retry Installing Kerberos Clients skips hosts were it failed (if lost heartbeat) (alexantonenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/0d84a7bf Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/0d84a7bf Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/0d84a7bf Branch: refs/heads/branch-dev-patch-upgrade Commit: 0d84a7bf39f9127889f216ce4c882534aaaaa5af Parents: 3d99106 Author: Alex Antonenko <hiv...@gmail.com> Authored: Tue Sep 13 18:07:46 2016 +0300 Committer: Alex Antonenko <hiv...@gmail.com> Committed: Tue Sep 13 20:22:15 2016 +0300 ---------------------------------------------------------------------- .../main/admin/kerberos/step3_controller.js | 54 +++++++++++++++- .../app/templates/main/admin/kerberos/step3.hbs | 6 ++ ambari-web/app/utils/ajax/ajax.js | 4 ++ .../app/views/main/admin/kerberos/step3_view.js | 29 ++++++++- .../admin/kerberos/step3_controller_test.js | 66 +++++++++++++++++++- 5 files changed, 151 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/0d84a7bf/ambari-web/app/controllers/main/admin/kerberos/step3_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/kerberos/step3_controller.js b/ambari-web/app/controllers/main/admin/kerberos/step3_controller.js index a244348..15be4f9 100644 --- a/ambari-web/app/controllers/main/admin/kerberos/step3_controller.js +++ b/ambari-web/app/controllers/main/admin/kerberos/step3_controller.js @@ -22,7 +22,7 @@ App.KerberosWizardStep3Controller = App.KerberosProgressPageController.extend({ serviceName: 'KERBEROS', componentName: 'KERBEROS_CLIENT', ignore: undefined, - + heartBeatLostHosts: [], commands: ['installKerberos', 'testKerberos'], loadStep: function () { @@ -30,6 +30,11 @@ App.KerberosWizardStep3Controller = App.KerberosProgressPageController.extend({ this.enableDisablePreviousSteps(); }, + clearStep: function() { + this.get('heartBeatLostHosts').clear(); + this._super(); + }, + installKerberos: function() { var self = this; this.getKerberosClientState().done(function(data) { @@ -52,6 +57,21 @@ App.KerberosWizardStep3Controller = App.KerberosProgressPageController.extend({ }); }, + /** + * Get hosts with HEARTBEAT_LOST state. + * + * @return {$.Deferred.promise} promise + */ + getHeartbeatLostHosts: function() { + return App.ajax.send({ + name: 'hosts.heartbeat_lost', + sender: this, + data: { + clusterName: App.get('clusterName') + } + }); + }, + getKerberosClientState: function() { return App.ajax.send({ name: 'common.service_component.info', @@ -116,6 +136,34 @@ App.KerberosWizardStep3Controller = App.KerberosProgressPageController.extend({ if (this.get('showIgnore')) { this.set('isSubmitDisabled', !this.get('ignore')); } - }.observes('ignore', 'showIgnore') -}); + }.observes('ignore', 'showIgnore'), + + retryTask: function() { + this._super(); + // retry from the first task (installKerberos) if there is any host in HEARTBEAT_LOST state. + if (this.get('heartBeatLostHosts').length) { + this.get('tasks').setEach('status', 'PENDING'); + this.get('tasks').setEach('showRetry', false); + this.get('heartBeatLostHosts').clear(); + } + }, + /** + * Check for complete status and determines: + * - if there are any hosts in HEARTBEAT_LOST state. In this case warn about hosts and make step FAILED. + * + * @return {undefined} + */ + statusDidChange: function() { + var self = this; + if (this.get('completedStatuses').contains(this.get('status'))) { + this.getHeartbeatLostHosts().then(function(data) { + var hostNames = Em.getWithDefault(data || {}, 'items', []).mapProperty('Hosts.host_name'); + if (hostNames.length) { + self.set('heartBeatLostHosts', hostNames.uniq()); + self.get('tasks').objectAt(0).set('status', 'FAILED'); + } + }); + } + }.observes('status') +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/0d84a7bf/ambari-web/app/templates/main/admin/kerberos/step3.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/admin/kerberos/step3.hbs b/ambari-web/app/templates/main/admin/kerberos/step3.hbs index 7e576b8..c9e0446 100644 --- a/ambari-web/app/templates/main/admin/kerberos/step3.hbs +++ b/ambari-web/app/templates/main/admin/kerberos/step3.hbs @@ -76,6 +76,12 @@ <label>{{view Em.Checkbox classNames="checkbox" checkedBinding="ignore"}} {{t admin.kerberos.wizard.step3.checkbox.ignoreAndProceed.label}}</label> </div> {{/if}} + {{#if view.isHostHeartbeatLost}} + <p class="alert alert-danger">{{view.resultMsg}} + <a href="javascript:void(null)" + data-toggle="modal" {{action showHostsWithLostHeartBeat target="view"}}>{{t common.showDetails}}</a> + </p> + {{/if}} {{else}} {{view App.SpinnerView}} {{/if}} http://git-wip-us.apache.org/repos/asf/ambari/blob/0d84a7bf/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 e8c4b97..70c73be 100644 --- a/ambari-web/app/utils/ajax/ajax.js +++ b/ambari-web/app/utils/ajax/ajax.js @@ -2539,6 +2539,10 @@ var urls = { 'real': '/clusters/{clusterName}/hosts?fields=host_components/HostRoles/state&minimal_response=true', 'mock': '/data/hosts/HDP2/hosts.json' }, + 'hosts.heartbeat_lost': { + 'real': '/clusters/{clusterName}/hosts?Hosts/host_state=HEARTBEAT_LOST', + 'mock': '' + }, 'host_components.all': { 'real': '/clusters/{clusterName}/host_components?fields=HostRoles/host_name&minimal_response=true', 'mock': '' http://git-wip-us.apache.org/repos/asf/ambari/blob/0d84a7bf/ambari-web/app/views/main/admin/kerberos/step3_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/admin/kerberos/step3_view.js b/ambari-web/app/views/main/admin/kerberos/step3_view.js index a499a82..f859027 100644 --- a/ambari-web/app/views/main/admin/kerberos/step3_view.js +++ b/ambari-web/app/views/main/admin/kerberos/step3_view.js @@ -27,6 +27,29 @@ App.KerberosWizardStep3View = App.KerberosProgressPageView.extend({ submitButtonText: Em.I18n.t('common.next') + '→', - showBackButton: true - -}); \ No newline at end of file + showBackButton: true, + + isHostHeartbeatLost: function() { + return !Em.isEmpty(this.get('controller.heartBeatLostHosts')); + }.property('controller.heartBeatLostHosts.length'), + + resultMsg: function() { + if (this.get('isHostHeartbeatLost')) { + return Em.I18n.t('installer.step9.status.hosts.heartbeat_lost').format(this.get('controller.heartBeatLostHosts.length')); + } + return ''; + }.property('isHostHeartbeatLost'), + + showHostsWithLostHeartBeat: function() { + var self = this; + return App.ModalPopup.show({ + header: Em.I18n.t('installer.step9.host.heartbeat_lost.header'), + autoHeight: false, + secondary: null, + bodyClass: Em.View.extend({ + hosts: self.get('controller.heartBeatLostHosts'), + template: Em.Handlebars.compile('{{#each hostName in view.hosts}}<p>{{view.hostName}}</p>{{/each}}') + }) + }); + } +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/0d84a7bf/ambari-web/test/controllers/main/admin/kerberos/step3_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/admin/kerberos/step3_controller_test.js b/ambari-web/test/controllers/main/admin/kerberos/step3_controller_test.js index 875e0bc..dbe48d0 100644 --- a/ambari-web/test/controllers/main/admin/kerberos/step3_controller_test.js +++ b/ambari-web/test/controllers/main/admin/kerberos/step3_controller_test.js @@ -25,7 +25,7 @@ describe('App.KerberosWizardStep3Controller', function() { beforeEach(function() { controller = App.KerberosWizardStep3Controller.create({}); }); - + describe('#onTestKerberosError', function() { beforeEach(function(){ @@ -228,4 +228,66 @@ describe('App.KerberosWizardStep3Controller', function() { }); }); -}); \ No newline at end of file + + describe('#statusDidChange', function() { + var cases; + beforeEach(function() { + controller.set('status', 'PENDING'); + controller.set('tasks', [ + Em.Object.create({ + id: 0, + status: 'COMPLETED' + }), + Em.Object.create({ + id: 1, + status: 'COMPLETED' + }) + ]); + this.getHeartbeatLostHostsStub = sinon.stub(controller, 'getHeartbeatLostHosts'); + }); + afterEach(function() { + controller.getHeartbeatLostHosts.restore(); + }); + + cases = [ + { + m: 'Heartbeat lost host during kerberization', + heartBeatHosts: ['host1'], + getHeartbeatLostHostsResponse: { + items: [ + { + Hosts: { + host_name: 'host1' + } + } + ] + }, + expected: { + heartbeatHosts: ['host1'], + installClientsTaskStatus: ['FAILED'] + } + }, + { + m: 'All hosts in HEALTHY state', + heartBeatHosts: [], + getHeartbeatLostHostsResponse: { + items: [] + }, + expected: { + heartbeatHosts: [], + installClientsTaskStatus: ['COMPLETED'] + } + } + ]; + + cases.forEach(function(test) { + it(test.m, function() { + this.getHeartbeatLostHostsStub.returns($.Deferred().resolve(test.getHeartbeatLostHostsResponse).promise()); + controller.set('status', 'COMPLETED'); + controller.propertyDidChange('status'); + assert.sameMembers(controller.get('heartBeatLostHosts'), test.expected.heartbeatHosts, 'heartbeat lost host stored in controller'); + assert.equal(controller.get('tasks').objectAt(0).get('status'), test.expected.installClientsTaskStatus, 'Install Clients task status') + }); + }); + }); +});