You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2017/11/30 14:07:53 UTC
ambari git commit: UI changes for prompting user during registration
failure for new OS family (Sonia Garudi via ncole)
Repository: ambari
Updated Branches:
refs/heads/branch-feature-AMBARI-21674 a11a8712a -> d43882d1a
UI changes for prompting user during registration failure for new OS family (Sonia Garudi via ncole)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/d43882d1
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/d43882d1
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/d43882d1
Branch: refs/heads/branch-feature-AMBARI-21674
Commit: d43882d1aa55dc2f7e358fec176641b57a6c71f6
Parents: a11a871
Author: Nate Cole <nc...@hortonworks.com>
Authored: Thu Nov 30 09:07:47 2017 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Thu Nov 30 09:07:47 2017 -0500
----------------------------------------------------------------------
.../ambari/server/bootstrap/BSHostStatus.java | 9 ++
.../server/bootstrap/BSHostStatusCollector.java | 7 +
.../app/controllers/wizard/step3_controller.js | 114 +++++++++++++++
ambari-web/app/messages.js | 3 +
ambari-web/app/styles/wizard.less | 22 +++
ambari-web/app/templates/wizard/step3.hbs | 47 +++++++
.../test/controllers/wizard/step3_test.js | 140 +++++++++++++++++++
7 files changed, 342 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/d43882d1/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSHostStatus.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSHostStatus.java b/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSHostStatus.java
index 3d1b31c..a91a1f2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSHostStatus.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSHostStatus.java
@@ -41,7 +41,16 @@ public class BSHostStatus {
private String statusAction;
@XmlElement
private String log;
+ @XmlElement
+ private String osType;
+
+ public String getOsType() {
+ return osType;
+ }
+ public void setOsType(String osType) {
+ this.osType = osType;
+ }
public void setStatus(String status) {
this.status = status;
http://git-wip-us.apache.org/repos/asf/ambari/blob/d43882d1/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSHostStatusCollector.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSHostStatusCollector.java b/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSHostStatusCollector.java
index b72ca20..45e0870 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSHostStatusCollector.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/bootstrap/BSHostStatusCollector.java
@@ -79,6 +79,13 @@ class BSHostStatusCollector {
if (statusCode.equals("0")) {
status.setStatus("DONE");
}
+ //the status code 44 is returned if ambari-repo property isn't set for the host's os_type in ambari.properties file.
+ //'44:<os_type>' is written to the .done file for the respective host.
+ if (statusCode.startsWith("44")) {
+ String[] sc = statusCode.split(":");
+ status.setOsType(sc[1]);
+ statusCode = sc[0];
+ }
updateStatus(status, statusCode);
} catch (IOException e) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/d43882d1/ambari-web/app/controllers/wizard/step3_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step3_controller.js b/ambari-web/app/controllers/wizard/step3_controller.js
index 29393e3..5ff2cdc 100644
--- a/ambari-web/app/controllers/wizard/step3_controller.js
+++ b/ambari-web/app/controllers/wizard/step3_controller.js
@@ -184,6 +184,9 @@ App.WizardStep3Controller = Em.Controller.extend(App.ReloadPopupMixin, App.Check
this.set('isLoaded', false);
this.set('isSubmitDisabled', true);
this.set('stopChecking', false);
+ this.set('newAmbariOsTypes', []);
+ this.set('promptAmbariRepoUrl', false);
+ this.set('bootstrapInProgress', false);
},
/**
@@ -301,6 +304,24 @@ App.WizardStep3Controller = Em.Controller.extend(App.ReloadPopupMixin, App.Check
return App.showConfirmationPopup(function () {
App.router.send('removeHosts', hosts);
self.hosts.removeObjects(hosts);
+ hosts.forEach(function(_host) {
+ var ambariOsTypeIndex = -1;
+ self.newAmbariOsTypes.some(function(os, index) {
+ if (os.hosts.contains(_host.name)){
+ ambariOsTypeIndex = index;
+ return true;
+ }
+ });
+ if (ambariOsTypeIndex != -1) {
+ self.newAmbariOsTypes[ambariOsTypeIndex].hosts.removeObject(_host.name);
+ if (self.newAmbariOsTypes[ambariOsTypeIndex].hosts.length == 0) {
+ self.newAmbariOsTypes.removeAt(ambariOsTypeIndex);
+ }
+ if (!self.newAmbariOsTypes.length) {
+ self.set('promptAmbariRepoUrl', false);
+ }
+ }
+ });
self.stopRegistration();
if (!self.hosts.length) {
self.set('isSubmitDisabled', true);
@@ -371,6 +392,7 @@ App.WizardStep3Controller = Em.Controller.extend(App.ReloadPopupMixin, App.Check
* @method retryHosts
*/
retryHosts: function (hosts) {
+ this.set('promptAmbariRepoUrl', false);
var self = this;
var bootStrapData = JSON.stringify({
'verbose': true,
@@ -385,6 +407,7 @@ App.WizardStep3Controller = Em.Controller.extend(App.ReloadPopupMixin, App.Check
this.set('isHostsWarningsLoaded', false);
this.set('stopChecking', false);
this.set('isSubmitDisabled', true);
+ this.set('bootstrapInProgress', true);
if (this.get('content.installOptions.manualInstall')) {
this.startRegistration();
} else {
@@ -523,6 +546,37 @@ App.WizardStep3Controller = Em.Controller.extend(App.ReloadPopupMixin, App.Check
var installedHosts = App.Host.find().mapProperty('hostName');
var isErrorStatus = data.status == 'ERROR';
this.set('isBootstrapFailed', isErrorStatus);
+
+ this.set('bootstrapInProgress', keepPolling);
+ // check for prompting ambari repo url
+ if (!keepPolling && data.hostsStatus.someProperty('statusCode', "44")) {
+ data.hostsStatus.forEach(function(host) {
+ if (host.statusCode == 44) {
+ var ambariOsTypeIndex = -1;
+ this.newAmbariOsTypes.some(function(diffOs, index) {
+ if (diffOs.os_type == host.osType) {
+ ambariOsTypeIndex = index;
+ return true;
+ }
+ });
+ if (ambariOsTypeIndex == -1) {
+ var tmpNewAmbariOsType = {
+ 'os_type' : host.osType,
+ 'ambari_repo' : "",
+ 'hosts' : []
+ };
+ tmpNewAmbariOsType.hosts.push(host.hostName);
+ this.newAmbariOsTypes.pushObject(tmpNewAmbariOsType);
+ } else {
+ if (!this.newAmbariOsTypes[ambariOsTypeIndex].hosts.contains(host.hostName)){
+ this.newAmbariOsTypes[ambariOsTypeIndex].hosts.push(host.hostName);
+ }
+ }
+ }
+ },this);
+ this.set('promptAmbariRepoUrl',true);
+ }
+
if (isErrorStatus || data.hostsStatus.mapProperty('hostName').removeObjects(installedHosts).length != this.get('bootHosts').length) {
var hosts = this.get('bootHosts');
@@ -552,6 +606,66 @@ App.WizardStep3Controller = Em.Controller.extend(App.ReloadPopupMixin, App.Check
},
/**
+ * check ambari repository URL entered on the UI
+ * @method checkAmbariRepoUI
+ */
+ checkAmbariRepoUI : (function() {
+ var regex = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/;
+ this.newAmbariOsTypes.forEach(function(obj) {
+ if (obj.ambari_repo == '' || obj.ambari_repo == null) {
+ Em.set(obj, 'ambariRepoUIError', "");
+ Em.set(obj, 'hasError', false);
+ } else if (/\s/.test(obj.ambari_repo) || !regex.test(obj.ambari_repo)) {
+ Em.set(obj, 'ambariRepoUIError', Em.I18n.t('installer.step3.ambariRepoUIError.stringError'));
+ Em.set(obj, 'hasError', true);
+ } else {
+ Em.set(obj, 'ambariRepoUIError', "");
+ Em.set(obj, 'hasError', false);
+ }
+ }, this);
+ }).observes('newAmbariOsTypes.@each.ambari_repo'),
+
+ /**
+ * return true if 1 or more ostypes have invalid URL
+ * @type {bool}
+ */
+ invalidAmbariRepoUrlExists : (function() {
+ return this.newAmbariOsTypes.someProperty('hasError', true);
+ }).property('newAmbariOsTypes.@each.hasError'),
+
+ /**
+ * return true if all textboxes for ambari repo url are empty
+ * @type {bool}
+ */
+ allAmbariRepoUrlsEmpty : (function() {
+ return this.newAmbariOsTypes.getEach('ambari_repo').every(function(value) {
+ return value == null || value == "";
+ });
+ }).property('newAmbariOsTypes.@each.ambari_repo'),
+
+ /**
+ * check conditions to disable ambari repo submit button
+ * @type {bool}
+ */
+ checkAmbariRepoSubmitDisabled : function() {
+ return (this.get('isRegistrationInProgress') || !this.get('isWarningsLoaded')) || App.get('router.btnClickInProgress') || this.get('bootstrapInProgress');
+ }.property('isRegistrationInProgress', 'isWarningsLoaded', 'bootstrapInProgress'),
+
+ /**
+ * Is ambari repo submit button disabled
+ * @type {bool}
+ */
+ isAmbariRepoURLSubmitDisabled : Em.computed.or('invalidAmbariRepoUrlExists', 'allAmbariRepoUrlsEmpty', 'checkAmbariRepoSubmitDisabled'),
+
+ /**
+ * Do bootstrap calls with entered ambari repo url
+ * @method bootstrapWithAmbariRepoUrl
+ */
+ bootstrapWithAmbariRepoUrl : function() {
+
+ },
+
+ /**
* Start hosts registration
* @method startRegistration
*/
http://git-wip-us.apache.org/repos/asf/ambari/blob/d43882d1/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 390f803..a7a238c 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -871,6 +871,9 @@ Em.I18n.translations = {
'installer.step3.hostLogPopup.copy':'press CTRL+C',
'installer.step3.hostsTable.selectAll':'Select All Hosts',
'installer.step3.selectedHosts.popup.header':'Selected Hosts',
+ 'ambari.repository.url.os.textbox':'Please enter valid Ambari Repository URLs for the below OS types',
+ 'ambari.repository.baseUrl':'Ambari Repository Base URL',
+ 'installer.step3.ambariRepoUIError.stringError':'Please enter a valid URL',
'installer.step4.header':'Choose Services',
'installer.step4.body':'Choose which services you want to install on your cluster.',
http://git-wip-us.apache.org/repos/asf/ambari/blob/d43882d1/ambari-web/app/styles/wizard.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/wizard.less b/ambari-web/app/styles/wizard.less
index cb9eb92..fb51701 100644
--- a/ambari-web/app/styles/wizard.less
+++ b/ambari-web/app/styles/wizard.less
@@ -189,6 +189,28 @@
#warningsSection {
margin: 0px 10px;
}
+ .ambari-repo-url-panel {
+ p.help-block.validation-block {
+ &::before {
+ content: '\e083';
+ color: #EF6162;
+ }
+ }
+ .btn-area {
+ padding: 10px;
+ }
+ input {
+ width:85%;
+ }
+ td {
+ .onerror {
+ .ember-text-field {
+ border-color: #EF6162;
+ }
+ }
+ }
+ }
+
}
#step4, #step5, #step6 {
a.selected {
http://git-wip-us.apache.org/repos/asf/ambari/blob/d43882d1/ambari-web/app/templates/wizard/step3.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/wizard/step3.hbs b/ambari-web/app/templates/wizard/step3.hbs
index e00012c..571c86e 100644
--- a/ambari-web/app/templates/wizard/step3.hbs
+++ b/ambari-web/app/templates/wizard/step3.hbs
@@ -140,6 +140,53 @@
{{/unless}}
</div>
{{/unless}}
+
+ {{#if promptAmbariRepoUrl}}
+ <div class="ambari-repo-url-panel">
+ <div class="step-title"> <p>Ambari Repositories</p></div>
+ <div class="step-description">
+ <div class="alert alert-info">
+ <label>{{t ambari.repository.url.os.textbox}}</label>
+ </div>
+ </div>
+ <table class="table table-hover">
+ <thead>
+ <tr>
+ <th class="col-sm-2">{{t common.os}} </th>
+ <th class="col-sm-3">{{t ambari.repository.baseUrl}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {{#each os in newAmbariOsTypes}}
+ <tr>
+ <td class="col-sm-2">{{os.os_type }}</td>
+ <td class="col-sm-9" colspan="2">
+ <table class="table table-condensed no-borders inner-table">
+ <tbody>
+ <tr>
+ <td class="col-sm-3" {{bindAttr class="os.hasError:onerror"}}>{{view Ember.TextField valueBinding="os.ambari_repo" }}</td>
+ </tr>
+ <tr>
+ <td class="col-sm-3">
+ {{#if os.hasError}}
+ <p class="help-block validation-block col-sm-9" {{QAAttr "ambari-repo-validation"}}>{{os.ambariRepoUIError}}</p>
+ {{/if}}
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ {{/each}}
+ </tbody>
+ </table>
+
+ <div class="btn-area">
+ <button type="button" class="btn" {{bindAttr disabled="isAmbariRepoURLSubmitDisabled" }} {{action bootstrapWithAmbariRepoUrl target="controller"}}>Validate
+ </div>
+ </div>
+ {{/if}}
+
</div>
</div>
</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/d43882d1/ambari-web/test/controllers/wizard/step3_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/wizard/step3_test.js b/ambari-web/test/controllers/wizard/step3_test.js
index b8bc794..be1affe 100644
--- a/ambari-web/test/controllers/wizard/step3_test.js
+++ b/ambari-web/test/controllers/wizard/step3_test.js
@@ -378,6 +378,41 @@ describe('App.WizardStep3Controller', function () {
expect(c.get('isSubmitDisabled')).to.equal(true);
});
+ it('should remove ambari repo prompt if no host of os_type exist', function () {
+ var hosts = [
+ Em.Object.create({name: 'host1'}),
+ Em.Object.create({name: 'host2'})
+ ];
+ c.reopen({
+ hosts: hosts,
+ promptAmbariRepoUrl: true,
+ newAmbariOsTypes : [
+ Em.Object.create({os_type : 'os1', hosts : ['host2']})
+ ]
+ });
+ var removeHosts = [{name: 'host2'}];
+ c.removeHosts(removeHosts).onPrimary();;
+ expect(c.get('promptAmbariRepoUrl')).to.equal(false);
+ });
+
+ it('should not remove ambari repo prompt if a host of os_type exist', function () {
+ var hosts = [
+ Em.Object.create({name: 'host1'}),
+ Em.Object.create({name: 'host2'}),
+ Em.Object.create({name: 'host3'})
+ ];
+ c.reopen({
+ hosts: hosts,
+ promptAmbariRepoUrl: true,
+ newAmbariOsTypes : [
+ Em.Object.create({os_type : 'os1', hosts : ['host2','host3']})
+ ]
+ });
+ var removeHosts = [{name: 'host2'}];
+ c.removeHosts(removeHosts).onPrimary();;
+ expect(c.get('promptAmbariRepoUrl')).to.equal(true);
+ });
+
});
describe('#removeSelectedHosts', function () {
@@ -2560,6 +2595,111 @@ describe('App.WizardStep3Controller', function () {
});
+ describe('#doBootstrapSuccessCallback', function () {
+
+ it('should prompt for ambari repo url if os_type of host added is different', function () {
+ c.reopen({
+ bootHosts: [
+ Em.Object.create({name: 'host1', bootStatus: 'FAILED'})
+ ],
+ newAmbariOsTypes: []
+ });
+ var data1 = {
+ status: 'ERROR',
+ hostsStatus: [
+ Em.Object.create({hostName: 'host1', status: 'FAILED', statusCode: '44', osType: 'os1', log: 'log'})
+ ]
+ };
+ c.doBootstrapSuccessCallback(data1);
+ expect(c.get('promptAmbariRepoUrl')).to.equal(true);
+ });
+ });
+
+ describe('#checkAmbariRepoUI', function () {
+
+ it('check space', function () {
+ var newAmbariOsTypes = [
+ Em.Object.create({os_type : 'os1', ambari_repo : "ambari repo", hosts : ['host1']})
+ ];
+ c.reopen({
+ newAmbariOsTypes: newAmbariOsTypes
+ });
+ c.checkAmbariRepoUI();
+ expect(c.get('newAmbariOsTypes')[0].hasError).to.equal(true);
+ expect(c.get('newAmbariOsTypes')[0].ambariRepoUIError).to.equal("Please enter a valid URL");
+ });
+
+ it('check invalid url', function () {
+ var newAmbariOsTypes = [
+ Em.Object.create({os_type : 'os1', ambari_repo : "http//ambari-repo", hosts : ['host1']})
+ ];
+ c.reopen({
+ newAmbariOsTypes: newAmbariOsTypes
+ });
+ c.checkAmbariRepoUI();
+ expect(c.get('newAmbariOsTypes')[0].hasError).to.equal(true);
+ expect(c.get('newAmbariOsTypes')[0].ambariRepoUIError).to.equal("Please enter a valid URL");
+ });
+ });
+
+ describe('#isAmbariRepoURLSubmitDisabled', function () {
+
+ var cases = [
+ {
+ allAmbariRepoUrlsEmpty: true,
+ invalidAmbariRepoUrlExists: false,
+ isAmbariRepoURLSubmitDisabled: true,
+ description: 'all textboxes are empty',
+ title: 'all empty '
+ },
+ {
+ allAmbariRepoUrlsEmpty: false,
+ invalidAmbariRepoUrlExists: true,
+ isAmbariRepoURLSubmitDisabled: true,
+ description: 'multiple textboxes with some empty and some with invalid urls',
+ title: 'has invalid, has empty'
+ },
+ {
+ allAmbariRepoUrlsEmpty: false,
+ invalidAmbariRepoUrlExists: false,
+ isAmbariRepoURLSubmitDisabled: false,
+ description: 'multiple textboxes with some empty and some with valid urls',
+ title: 'has valid, has empty'
+ },
+ {
+ allAmbariRepoUrlsEmpty: false,
+ invalidAmbariRepoUrlExists: false,
+ isAmbariRepoURLSubmitDisabled: false,
+ description: 'all textboxes valid urls',
+ title: 'all valid'
+ }
+ ];
+
+ cases.forEach(function (item) {
+
+ describe(item.description, function () {
+
+ beforeEach(function () {
+ c.reopen({
+ checkAmbariRepoSubmitDisabled: false,
+ allAmbariRepoUrlsEmpty: item.allAmbariRepoUrlsEmpty,
+ invalidAmbariRepoUrlExists: item.invalidAmbariRepoUrlExists
+ });
+ sinon.stub(App, 'get').withArgs('router.btnClickInProgress').returns(false);
+ });
+
+ afterEach(function () {
+ App.get.restore();
+ });
+
+ it(item.title, function () {
+ expect(c.get('isAmbariRepoURLSubmitDisabled')).to.equal(item.isAmbariRepoURLSubmitDisabled);
+ });
+ });
+ });
+
+ });
+
describe('#getJDKNameSuccessCallback', function () {
it('should set proper data to controller properties', function () {