Repository: ambari Updated Branches: refs/heads/branch-2.2 dd532e13f -> fc7338795
AMBARI-15657: HAWQ config should not allow multiple Master/Segment directories (Lav Jain via mithmatt) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/fc733879 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/fc733879 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/fc733879 Branch: refs/heads/branch-2.2 Commit: fc7338795ca7ef157afff031ed96c2d1ec7962df Parents: dd532e1 Author: Matt <[email protected]> Authored: Tue Apr 5 11:03:16 2016 -0700 Committer: Matt <[email protected]> Committed: Tue Apr 5 11:03:16 2016 -0700 ---------------------------------------------------------------------- .../HAWQ/2.0.0/configuration/hawq-site.xml | 5 +-- .../HAWQ/2.0.0/themes/theme.json | 4 +-- .../stacks/HDP/2.3/services/stack_advisor.py | 17 +++++++++ .../stacks/2.3/common/test_stack_advisor.py | 36 ++++++++++++++++++++ ambari-web/app/messages.js | 1 + ambari-web/app/mixins/common/serverValidator.js | 11 ++++-- .../configs/objects/service_config_property.js | 3 ++ ambari-web/app/styles/application.less | 16 ++++++--- .../config_recommendation_popup.hbs | 25 ++++++++++---- .../configs/service_config_layout_tab_view.js | 2 +- 10 files changed, 100 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/fc733879/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/configuration/hawq-site.xml ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/configuration/hawq-site.xml b/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/configuration/hawq-site.xml index ec7275f..170e8cf 100644 --- a/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/configuration/hawq-site.xml +++ b/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/configuration/hawq-site.xml @@ -88,7 +88,8 @@ <display-name>HAWQ Master Directory</display-name> <value>/data/hawq/master</value> <description> - The directory of HAWQ master. + The base path for the HAWQ master data directory. Multiple directories are not allowed. + The default is /data/hawq/master. </description> <value-attributes> <type>directory</type> @@ -102,7 +103,7 @@ <display-name>HAWQ Segment Directory</display-name> <value>/data/hawq/segment</value> <description> - The base path for the HAWQ segment data directory. + The base path for the HAWQ segment data directory. Multiple directories are not allowed. The default is /data/hawq/segment. </description> <value-attributes> http://git-wip-us.apache.org/repos/asf/ambari/blob/fc733879/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/themes/theme.json ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/themes/theme.json b/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/themes/theme.json index a23afe6..e4d1c45 100644 --- a/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/themes/theme.json +++ b/ambari-server/src/main/resources/common-services/HAWQ/2.0.0/themes/theme.json @@ -136,13 +136,13 @@ { "config":"hawq-site/hawq_master_directory", "widget":{ - "type":"text-field" + "type":"directory" } }, { "config":"hawq-site/hawq_segment_directory", "widget":{ - "type":"text-field" + "type":"directory" } }, { http://git-wip-us.apache.org/repos/asf/ambari/blob/fc733879/ambari-server/src/main/resources/stacks/HDP/2.3/services/stack_advisor.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/services/stack_advisor.py b/ambari-server/src/main/resources/stacks/HDP/2.3/services/stack_advisor.py index 6e1c148..21b4bff 100644 --- a/ambari-server/src/main/resources/stacks/HDP/2.3/services/stack_advisor.py +++ b/ambari-server/src/main/resources/stacks/HDP/2.3/services/stack_advisor.py @@ -17,6 +17,7 @@ See the License for the specific language governing permissions and limitations under the License. """ import os +import re import fnmatch import socket @@ -942,6 +943,14 @@ class HDP23StackAdvisor(HDP22StackAdvisor): "It is not advisable to have " + display_name + " at " + root_dir +". Consider creating a sub directory for HAWQ")}) + def checkForMultipleDirs(self, properties, validationItems, prop_name, display_name): + # check for delimiters space, comma, colon and semi-colon + if prop_name in properties and len(re.sub(r'[,;:]', ' ', properties[prop_name]).split(' ')) > 1: + validationItems.append({"config-name": prop_name, + "item": self.getErrorItem( + "Multiple directories for " + display_name + " are not allowed.")}) + + def validateHAWQSiteConfigurations(self, properties, recommendedDefaults, configurations, services, hosts): hawq_site = properties validationItems = [] @@ -965,6 +974,14 @@ class HDP23StackAdvisor(HDP22StackAdvisor): for property_name, display_name in directories.iteritems(): self.validateIfRootDir(properties, validationItems, property_name, display_name) + # 2.1 Check if any master or segment directories has multiple values + directories = { + 'hawq_master_directory': 'HAWQ Master directory', + 'hawq_segment_directory': 'HAWQ Segment directory' + } + for property_name, display_name in directories.iteritems(): + self.checkForMultipleDirs(properties, validationItems, property_name, display_name) + # 3. Check YARN RM address properties YARN = "YARN" servicesList = [service["StackServices"]["service_name"] for service in services["services"]] http://git-wip-us.apache.org/repos/asf/ambari/blob/fc733879/ambari-server/src/test/python/stacks/2.3/common/test_stack_advisor.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/python/stacks/2.3/common/test_stack_advisor.py b/ambari-server/src/test/python/stacks/2.3/common/test_stack_advisor.py index dc478d9..38f5415 100644 --- a/ambari-server/src/test/python/stacks/2.3/common/test_stack_advisor.py +++ b/ambari-server/src/test/python/stacks/2.3/common/test_stack_advisor.py @@ -2021,6 +2021,42 @@ class TestHDP23StackAdvisor(TestCase): self.assertEqual(len(problems), 2) self.assertEqual(problems_dict, expected_warnings) + # Test hawq_master_directory multiple directories validation + configurations["hawq-site"] = {"properties": {"hawq_master_directory": "/data/hawq/master", + "hawq_segment_directory": "/data/hawq/segment"}} + properties = configurations["hawq-site"]["properties"] + problems = self.stackAdvisor.validateHAWQSiteConfigurations(properties, defaults, configurations, services, hosts) + problems_dict = {} + self.assertEqual(len(problems), 0) + expected_warnings = {} + self.assertEqual(problems_dict, expected_warnings) + + configurations["hawq-site"] = {"properties": {"hawq_master_directory": "/data/hawq/master1,/data/hawq/master2", + "hawq_segment_directory": "/data/hawq/segment1 /data/hawq/segment2"}} + properties = configurations["hawq-site"]["properties"] + problems = self.stackAdvisor.validateHAWQSiteConfigurations(properties, defaults, configurations, services, hosts) + problems_dict = {} + for problem in problems: + problems_dict[problem['config-name']] = problem + self.assertEqual(len(problems), 2) + expected_warnings = { + 'hawq_master_directory': { + 'config-type': 'hawq-site', + 'message': 'Multiple directories for HAWQ Master directory are not allowed.', + 'type': 'configuration', + 'config-name': 'hawq_master_directory', + 'level': 'ERROR' + }, + 'hawq_segment_directory': { + 'config-type': 'hawq-site', + 'message': 'Multiple directories for HAWQ Segment directory are not allowed.', + 'type': 'configuration', + 'config-name': 'hawq_segment_directory', + 'level': 'ERROR' + } + } + self.assertEqual(problems_dict, expected_warnings) + # Test hawq_global_rm_type validation services = { "services" : [ http://git-wip-us.apache.org/repos/asf/ambari/blob/fc733879/ambari-web/app/messages.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js index 7ef7b7b..2f844c6 100644 --- a/ambari-web/app/messages.js +++ b/ambari-web/app/messages.js @@ -799,6 +799,7 @@ Em.I18n.translations = { 'installer.step7.popup.validation.request.failed.body': 'The configuration changes could not be validated for consistency due to an unknown error. Your changes have not been saved yet. Would you like to proceed and save the changes?', 'installer.step7.popup.validation.warning.header': 'Configurations', 'installer.step7.popup.validation.warning.body': 'Some service configurations are not configured properly. We recommend you review and change the highlighted configuration values. Are you sure you want to proceed without correcting configurations?', + 'installer.step7.popup.validation.error.body': 'Service configurations resulted in validation errors. Please address them before proceeding.', 'installer.step7.popup.oozie.derby.warning': 'Derby is not recommended for production use. With Derby, Oozie Server HA and concurrent connection support will not be available.', 'installer.step7.oozie.database.new': 'New Derby Database', 'installer.step7.hive.database.new.mysql': 'New MySQL Database', http://git-wip-us.apache.org/repos/asf/ambari/blob/fc733879/ambari-web/app/mixins/common/serverValidator.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mixins/common/serverValidator.js b/ambari-web/app/mixins/common/serverValidator.js index ebb68ad..e66e329 100644 --- a/ambari-web/app/mixins/common/serverValidator.js +++ b/ambari-web/app/mixins/common/serverValidator.js @@ -393,7 +393,7 @@ App.ServerValidatorMixin = Em.Mixin.create({ body: Em.I18n.t('installer.step7.popup.validation.request.failed.body') }); } else if (this.get('configValidationWarning') || this.get('configValidationError')) { - // Motivation: for server-side validation warnings and EVEN errors allow user to continue wizard + // Motivation: for server-side validation warnings allow user to continue wizard var stepConfigs = self.get('name') === 'mainServiceInfoConfigsController' ? [self.get('selectedService')] : self.get('stepConfigs'); @@ -404,11 +404,13 @@ App.ServerValidatorMixin = Em.Mixin.create({ }); if (configsWithErrors) { return App.ModalPopup.show({ - header: Em. I18n.t('installer.step7.popup.validation.warning.header'), + header: Em.I18n.t('installer.step7.popup.validation.warning.header'), classNames: ['sixty-percent-width-modal','modal-full-width'], primary: Em.I18n.t('common.proceedAnyway'), primaryClass: 'btn-danger', marginBottom: 200, + // Do not allow "Proceed Anyway" for validation errors + disablePrimary: self.get('configValidationError'), onPrimary: function () { this.hide(); deferred.resolve(); @@ -424,7 +426,10 @@ App.ServerValidatorMixin = Em.Mixin.create({ bodyClass: Em.View.extend({ controller: self, templateName: require('templates/common/modal_popups/config_recommendation_popup'), - serviceConfigs: stepConfigs + serviceConfigs: stepConfigs, + messageBody: Em.I18n.t(self.get('configValidationError') + ? 'installer.step7.popup.validation.error.body' + : 'installer.step7.popup.validation.warning.body') }) }); } else { http://git-wip-us.apache.org/repos/asf/ambari/blob/fc733879/ambari-web/app/models/configs/objects/service_config_property.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models/configs/objects/service_config_property.js b/ambari-web/app/models/configs/objects/service_config_property.js index 328703a..f063fa0 100644 --- a/ambari-web/app/models/configs/objects/service_config_property.js +++ b/ambari-web/app/models/configs/objects/service_config_property.js @@ -351,6 +351,9 @@ App.ServiceConfigProperty = Em.Object.extend({ case 'directories': return App.ServiceConfigTextArea; break; + case 'directory': + return App.ServiceConfigTextField; + break; case 'content': return App.ServiceConfigTextAreaContent; break; http://git-wip-us.apache.org/repos/asf/ambari/blob/fc733879/ambari-web/app/styles/application.less ---------------------------------------------------------------------- diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less index 77834f5..2819a08 100644 --- a/ambari-web/app/styles/application.less +++ b/ambari-web/app/styles/application.less @@ -5824,19 +5824,25 @@ input[type="radio"].align-checkbox, input[type="checkbox"].align-checkbox { } } +@warning-background: #fcf8e3; +@error-background: #f2dede; + .table td.no-borders { border-top: none; } -.table td.error { background-color: #f2dede; } -.table td.warning { background-color: #fcf8e3; } +.table td.error { background-color: @error-background; } +.table td.warning { background-color: @warning-background; } #config-validation-warnings { table { tbody{ tr { - background:#fcf8e3; + &.warning { + background: @warning-background; + } + &.error { + background: @error-background; + } border:1px solid #c09853; - border-right:none; td { - min-width: 150px; .property-message { font-weight: bold; } http://git-wip-us.apache.org/repos/asf/ambari/blob/fc733879/ambari-web/app/templates/common/modal_popups/config_recommendation_popup.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/common/modal_popups/config_recommendation_popup.hbs b/ambari-web/app/templates/common/modal_popups/config_recommendation_popup.hbs index f58e086..4243137 100644 --- a/ambari-web/app/templates/common/modal_popups/config_recommendation_popup.hbs +++ b/ambari-web/app/templates/common/modal_popups/config_recommendation_popup.hbs @@ -16,11 +16,12 @@ * limitations under the License. }} -<p>{{t installer.step7.popup.validation.warning.body}}</p> +<p>{{view.messageBody}}</p> <div id="config-validation-warnings" class="limited-height-2"> <table class="table no-borders"> <thead> <tr> + <th>{{t common.type}}</th> <th>{{t common.service}}</th> <th>{{t common.property}}</th> <th>{{t common.value}}</th> @@ -32,24 +33,34 @@ {{#each property in service.configs}} {{#if property.isVisible}} {{#unless property.hiddenBySection}} - {{#if property.warn}} - <tr> + {{#if property.error}} + <tr class="error"> + <td>{{t common.error}}</td> <td>{{property.serviceName}}</td> <td>{{property.name}}</td> <td>{{property.value}}</td> <td> - <div class="property-message">{{property.warnMessage}}</div> + <div class="property-message">{{property.errorMessage}}</div> <div class="property-description">{{property.description}}</div> </td> </tr> {{/if}} - {{#if property.error}} - <tr> + {{/unless}} + {{/if}} + {{/each}} + {{/each}} + {{#each service in view.serviceConfigs}} + {{#each property in service.configs}} + {{#if property.isVisible}} + {{#unless property.hiddenBySection}} + {{#if property.warn}} + <tr class="warning"> + <td>{{t common.warning}}</td> <td>{{property.serviceName}}</td> <td>{{property.name}}</td> <td>{{property.value}}</td> <td> - <div class="property-message">{{property.errorMessage}}</div> + <div class="property-message">{{property.warnMessage}}</div> <div class="property-description">{{property.description}}</div> </td> </tr> http://git-wip-us.apache.org/repos/asf/ambari/blob/fc733879/ambari-web/app/views/common/configs/service_config_layout_tab_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/configs/service_config_layout_tab_view.js b/ambari-web/app/views/common/configs/service_config_layout_tab_view.js index 9029448..13d009e 100644 --- a/ambari-web/app/views/common/configs/service_config_layout_tab_view.js +++ b/ambari-web/app/views/common/configs/service_config_layout_tab_view.js @@ -55,7 +55,7 @@ App.ServiceConfigLayoutTabView = Em.View.extend(App.ConfigOverridable, { widgetTypeMap: { checkbox: App.CheckboxConfigWidgetView, combo: App.ComboConfigWidgetView, - directory: App.DirectoryConfigWidgetView, + directory: App.TextFieldConfigWidgetView, directories: App.DirectoryConfigWidgetView, list: App.ListConfigWidgetView, password: App.PasswordConfigWidgetView,
