You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by mi...@apache.org on 2016/04/05 20:01:44 UTC

ambari git commit: AMBARI-15657: HAWQ config should not allow multiple Master/Segment directories (Lav Jain via mithmatt)

Repository: ambari
Updated Branches:
  refs/heads/trunk dc088141a -> 867213892


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/86721389
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/86721389
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/86721389

Branch: refs/heads/trunk
Commit: 8672138926f2b88c6d798a470b4beb279f4c071f
Parents: dc08814
Author: Matt <mm...@pivotal.io>
Authored: Tue Apr 5 11:00:49 2016 -0700
Committer: Matt <mm...@pivotal.io>
Committed: Tue Apr 5 11:00:49 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/86721389/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/86721389/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/86721389/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 8cafe6a..3a65541 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
 
@@ -956,6 +957,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 = []
@@ -979,6 +988,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/86721389/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 4fe8a0e..6c9fd46 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
@@ -2034,6 +2034,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/86721389/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index f68d97a..8e32c84 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -843,6 +843,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/86721389/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 99a5921..fca1550 100644
--- a/ambari-web/app/mixins/common/serverValidator.js
+++ b/ambari-web/app/mixins/common/serverValidator.js
@@ -295,7 +295,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');
@@ -306,11 +306,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();
@@ -326,7 +328,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/86721389/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 290356c..e7eaebd 100644
--- a/ambari-web/app/models/configs/objects/service_config_property.js
+++ b/ambari-web/app/models/configs/objects/service_config_property.js
@@ -313,6 +313,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/86721389/ambari-web/app/styles/application.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less
index 683ba24..7c057ac 100644
--- a/ambari-web/app/styles/application.less
+++ b/ambari-web/app/styles/application.less
@@ -5926,19 +5926,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/86721389/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/86721389/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 694e883..30ffadf 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
@@ -53,7 +53,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,