Browse Source

AMBARI-3031. Set mapreduce.admin.user.env in mapred-site.xml. (srimanth)

Srimanth Gunturi 11 years ago
parent
commit
a706dd95ab

+ 10 - 0
ambari-server/src/main/resources/stacks/HDP/2.0.5/services/MAPREDUCE2/configuration/mapred-site.xml

@@ -369,4 +369,14 @@
     </description>
     </description>
   </property>
   </property>
 
 
+  <property>
+    <name>mapreduce.admin.user.env</name>
+    <value>LD_LIBRARY_PATH=/usr/lib/hadoop/lib/native:/usr/lib/hadoop/lib/native/`$JAVA_HOME/bin/java -d32 -version &amp;&gt; /dev/null;if [ $? -eq 0 ]; then echo Linux-i386-32; else echo Linux-amd64-64;fi`</value>
+    <description>
+      Additional execution environment entries for map and reduce task processes.
+      This is not an additive property. You must preserve the original value if
+      you want your map and reduce tasks to have access to native libraries (compression, etc)
+    </description>
+  </property>
+
 </configuration>
 </configuration>

+ 10 - 0
ambari-server/src/main/resources/stacks/HDPLocal/2.0.5/services/MAPREDUCE2/configuration/mapred-site.xml

@@ -369,4 +369,14 @@
     </description>
     </description>
   </property>
   </property>
 
 
+  <property>
+    <name>mapreduce.admin.user.env</name>
+    <value>LD_LIBRARY_PATH=/usr/lib/hadoop/lib/native:/usr/lib/hadoop/lib/native/`$JAVA_HOME/bin/java -d32 -version &amp;&gt; /dev/null;if [ $? -eq 0 ]; then echo Linux-i386-32; else echo Linux-amd64-64;fi`</value>
+    <description>
+      Additional execution environment entries for map and reduce task processes.
+      This is not an additive property. You must preserve the original value if
+      you want your map and reduce tasks to have access to native libraries (compression, etc)
+    </description>
+  </property>
+
 </configuration>
 </configuration>

+ 4 - 4
ambari-web/app/controllers/main/service/info/configs.js

@@ -1350,7 +1350,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
         if (/_heapsize|_newsize|_maxnewsize$/.test(_globalSiteObj.name) && !heapsizeException.contains(_globalSiteObj.name)) {
         if (/_heapsize|_newsize|_maxnewsize$/.test(_globalSiteObj.name) && !heapsizeException.contains(_globalSiteObj.name)) {
           _globalSiteObj.value += "m";
           _globalSiteObj.value += "m";
         }
         }
-        globalSiteProperties[_globalSiteObj.name] = _globalSiteObj.value;
+        globalSiteProperties[_globalSiteObj.name] = App.config.escapeXMLCharacters(_globalSiteObj.value);
         this.recordHostOverride(_globalSiteObj, 'global', tagName, this);
         this.recordHostOverride(_globalSiteObj, 'global', tagName, this);
         //console.log("TRACE: name of the global property is: " + _globalSiteObj.name);
         //console.log("TRACE: name of the global property is: " + _globalSiteObj.name);
         //console.log("TRACE: value of the global property is: " + _globalSiteObj.value);
         //console.log("TRACE: value of the global property is: " + _globalSiteObj.value);
@@ -1424,7 +1424,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
     var coreSiteObj = this.get('uiConfigs').filterProperty('filename', 'core-site.xml');
     var coreSiteObj = this.get('uiConfigs').filterProperty('filename', 'core-site.xml');
     var coreSiteProperties = {};
     var coreSiteProperties = {};
     coreSiteObj.forEach(function (_coreSiteObj) {
     coreSiteObj.forEach(function (_coreSiteObj) {
-      coreSiteProperties[_coreSiteObj.name] = _coreSiteObj.value;
+      coreSiteProperties[_coreSiteObj.name] = App.config.escapeXMLCharacters(_coreSiteObj.value);
       this.recordHostOverride(_coreSiteObj, 'core-site', tagName, this);
       this.recordHostOverride(_coreSiteObj, 'core-site', tagName, this);
     }, this);
     }, this);
     return {"type": "core-site", "tag": tagName, "properties": coreSiteProperties};
     return {"type": "core-site", "tag": tagName, "properties": coreSiteProperties};
@@ -1445,12 +1445,12 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
       siteObj = this.getHiveSiteObj(siteObj);
       siteObj = this.getHiveSiteObj(siteObj);
     }
     }
     siteObj.forEach(function (_siteObj) {
     siteObj.forEach(function (_siteObj) {
-      siteProperties[_siteObj.name] = _siteObj.value;
+      siteProperties[_siteObj.name] = App.config.escapeXMLCharacters(_siteObj.value);
       this.recordHostOverride(_siteObj, siteName, tagName, this);
       this.recordHostOverride(_siteObj, siteName, tagName, this);
     }, this);
     }, this);
     return {"type": siteName, "tag": tagName, "properties": siteProperties};
     return {"type": siteName, "tag": tagName, "properties": siteProperties};
   },
   },
-
+  
   /**
   /**
    * create site object for Oozie
    * create site object for Oozie
    * @param siteObj
    * @param siteObj

+ 13 - 13
ambari-web/app/controllers/wizard/step8_controller.js

@@ -1375,7 +1375,7 @@ App.WizardStep8Controller = Em.Controller.extend({
         if (/_heapsize|_newsize|_maxnewsize$/.test(_globalSiteObj.name) && !heapsizeException.contains(_globalSiteObj.name)) {
         if (/_heapsize|_newsize|_maxnewsize$/.test(_globalSiteObj.name) && !heapsizeException.contains(_globalSiteObj.name)) {
           globalSiteProperties[_globalSiteObj.name] = _globalSiteObj.value + "m";
           globalSiteProperties[_globalSiteObj.name] = _globalSiteObj.value + "m";
         } else {
         } else {
-          globalSiteProperties[_globalSiteObj.name] = _globalSiteObj.value;
+          globalSiteProperties[_globalSiteObj.name] = App.config.escapeXMLCharacters(_globalSiteObj.value);
         }
         }
         console.log("STEP8: name of the global property is: " + _globalSiteObj.name);
         console.log("STEP8: name of the global property is: " + _globalSiteObj.name);
         console.log("STEP8: value of the global property is: " + _globalSiteObj.value);
         console.log("STEP8: value of the global property is: " + _globalSiteObj.value);
@@ -1410,11 +1410,11 @@ App.WizardStep8Controller = Em.Controller.extend({
     }
     }
     coreSiteObj.forEach(function (_coreSiteObj) {
     coreSiteObj.forEach(function (_coreSiteObj) {
       if ((isOozieSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + oozieUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + oozieUser + '.groups')) && (isHiveSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + hiveUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + hiveUser + '.groups')) && (isHcatSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + hcatUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + hcatUser + '.groups'))) {
       if ((isOozieSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + oozieUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + oozieUser + '.groups')) && (isHiveSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + hiveUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + hiveUser + '.groups')) && (isHcatSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + hcatUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + hcatUser + '.groups'))) {
-        coreSiteProperties[_coreSiteObj.name] = _coreSiteObj.value;
+        coreSiteProperties[_coreSiteObj.name] = App.config.escapeXMLCharacters(_coreSiteObj.value);
         this._recordHostOverrideFromObj(_coreSiteObj, 'core-site', 'version1', this);
         this._recordHostOverrideFromObj(_coreSiteObj, 'core-site', 'version1', this);
       }
       }
       if (isHCFSSelected && _coreSiteObj.name == "fs.default.name") {
       if (isHCFSSelected && _coreSiteObj.name == "fs.default.name") {
-        coreSiteProperties[_coreSiteObj.name] = this.get('globals').someProperty('name', 'fs_glusterfs_default_name') ? this.get('globals').findProperty('name', 'fs_glusterfs_default_name').value : null;
+        coreSiteProperties[_coreSiteObj.name] = this.get('globals').someProperty('name', 'fs_glusterfs_default_name') ? App.config.escapeXMLCharacters(this.get('globals').findProperty('name', 'fs_glusterfs_default_name').value) : null;
       }
       }
       console.log("STEP*: name of the property is: " + _coreSiteObj.name);
       console.log("STEP*: name of the property is: " + _coreSiteObj.name);
       console.log("STEP8: value of the property is: " + _coreSiteObj.value);
       console.log("STEP8: value of the property is: " + _coreSiteObj.value);
@@ -1426,7 +1426,7 @@ App.WizardStep8Controller = Em.Controller.extend({
     var hdfsSiteObj = this.get('configs').filterProperty('filename', 'hdfs-site.xml');
     var hdfsSiteObj = this.get('configs').filterProperty('filename', 'hdfs-site.xml');
     var hdfsProperties = {};
     var hdfsProperties = {};
     hdfsSiteObj.forEach(function (_configProperty) {
     hdfsSiteObj.forEach(function (_configProperty) {
-      hdfsProperties[_configProperty.name] = _configProperty.value;
+      hdfsProperties[_configProperty.name] = App.config.escapeXMLCharacters(_configProperty.value);
       this._recordHostOverrideFromObj(_configProperty, 'hdfs-site', 'version1', this);
       this._recordHostOverrideFromObj(_configProperty, 'hdfs-site', 'version1', this);
       console.log("STEP*: name of the property is: " + _configProperty.name);
       console.log("STEP*: name of the property is: " + _configProperty.name);
       console.log("STEP8: value of the property is: " + _configProperty.value);
       console.log("STEP8: value of the property is: " + _configProperty.value);
@@ -1438,7 +1438,7 @@ App.WizardStep8Controller = Em.Controller.extend({
     var hueSiteObj = this.get('configs').filterProperty('filename', 'hue-site.xml');
     var hueSiteObj = this.get('configs').filterProperty('filename', 'hue-site.xml');
     var hueProperties = {};
     var hueProperties = {};
     hueSiteObj.forEach(function (_configProperty) {
     hueSiteObj.forEach(function (_configProperty) {
-      hueProperties[_configProperty.name] = _configProperty.value;
+      hueProperties[_configProperty.name] = App.config.escapeXMLCharacters(_configProperty.value);
       this._recordHostOverrideFromObj(_configProperty, 'hue-site', 'version1', this);
       this._recordHostOverrideFromObj(_configProperty, 'hue-site', 'version1', this);
       console.log("STEP*: name of the property is: " + _configProperty.name);
       console.log("STEP*: name of the property is: " + _configProperty.name);
       console.log("STEP8: value of the property is: " + _configProperty.value);
       console.log("STEP8: value of the property is: " + _configProperty.value);
@@ -1450,7 +1450,7 @@ App.WizardStep8Controller = Em.Controller.extend({
     var configs = this.get('configs').filterProperty('filename', 'mapred-site.xml');
     var configs = this.get('configs').filterProperty('filename', 'mapred-site.xml');
     var mrProperties = {};
     var mrProperties = {};
     configs.forEach(function (_configProperty) {
     configs.forEach(function (_configProperty) {
-      mrProperties[_configProperty.name] = _configProperty.value;
+      mrProperties[_configProperty.name] = App.config.escapeXMLCharacters(_configProperty.value);
       this._recordHostOverrideFromObj(_configProperty, 'mapred-site', 'version1', this);
       this._recordHostOverrideFromObj(_configProperty, 'mapred-site', 'version1', this);
       console.log("STEP*: name of the property is: " + _configProperty.name);
       console.log("STEP*: name of the property is: " + _configProperty.name);
       console.log("STEP8: value of the property is: " + _configProperty.value);
       console.log("STEP8: value of the property is: " + _configProperty.value);
@@ -1462,7 +1462,7 @@ App.WizardStep8Controller = Em.Controller.extend({
     var configs = this.get('configs').filterProperty('filename', 'yarn-site.xml');
     var configs = this.get('configs').filterProperty('filename', 'yarn-site.xml');
     var mrProperties = {};
     var mrProperties = {};
     configs.forEach(function (_configProperty) {
     configs.forEach(function (_configProperty) {
-      mrProperties[_configProperty.name] = _configProperty.value;
+      mrProperties[_configProperty.name] = App.config.escapeXMLCharacters(_configProperty.value);
       this._recordHostOverrideFromObj(_configProperty, 'yarn-site', 'version1', this);
       this._recordHostOverrideFromObj(_configProperty, 'yarn-site', 'version1', this);
       console.log("STEP*: name of the property is: " + _configProperty.name);
       console.log("STEP*: name of the property is: " + _configProperty.name);
       console.log("STEP8: value of the property is: " + _configProperty.value);
       console.log("STEP8: value of the property is: " + _configProperty.value);
@@ -1474,7 +1474,7 @@ App.WizardStep8Controller = Em.Controller.extend({
     var configs = this.get('configs').filterProperty('filename', 'capacity-scheduler.xml');
     var configs = this.get('configs').filterProperty('filename', 'capacity-scheduler.xml');
     var csProperties = {};
     var csProperties = {};
     configs.forEach(function (_configProperty) {
     configs.forEach(function (_configProperty) {
-      csProperties[_configProperty.name] = _configProperty.value;
+      csProperties[_configProperty.name] = App.config.escapeXMLCharacters(_configProperty.value);
       this._recordHostOverrideFromObj(_configProperty, 'capacity-scheduler', 'version1', this);
       this._recordHostOverrideFromObj(_configProperty, 'capacity-scheduler', 'version1', this);
       console.log("STEP*: name of the property is: " + _configProperty.name);
       console.log("STEP*: name of the property is: " + _configProperty.name);
       console.log("STEP8: value of the property is: " + _configProperty.value);
       console.log("STEP8: value of the property is: " + _configProperty.value);
@@ -1486,7 +1486,7 @@ App.WizardStep8Controller = Em.Controller.extend({
     var configs = this.get('configs').filterProperty('filename', 'mapred-queue-acls.xml');
     var configs = this.get('configs').filterProperty('filename', 'mapred-queue-acls.xml');
     var mqProperties = {};
     var mqProperties = {};
     configs.forEach(function (_configProperty) {
     configs.forEach(function (_configProperty) {
-     mqProperties[_configProperty.name] = _configProperty.value;
+     mqProperties[_configProperty.name] = App.config.escapeXMLCharacters(_configProperty.value);
      this._recordHostOverrideFromObj(_configProperty, 'mapred-queue-acls', 'version1', this);
      this._recordHostOverrideFromObj(_configProperty, 'mapred-queue-acls', 'version1', this);
       console.log("STEP*: name of the property is: " + _configProperty.name);
       console.log("STEP*: name of the property is: " + _configProperty.name);
       console.log("STEP8: value of the property is: " + _configProperty.value);
       console.log("STEP8: value of the property is: " + _configProperty.value);
@@ -1498,7 +1498,7 @@ App.WizardStep8Controller = Em.Controller.extend({
     var configs = this.get('configs').filterProperty('filename', 'hbase-site.xml');
     var configs = this.get('configs').filterProperty('filename', 'hbase-site.xml');
     var hbaseProperties = {};
     var hbaseProperties = {};
     configs.forEach(function (_configProperty) {
     configs.forEach(function (_configProperty) {
-      hbaseProperties[_configProperty.name] = _configProperty.value;
+      hbaseProperties[_configProperty.name] = App.config.escapeXMLCharacters(_configProperty.value);
       this._recordHostOverrideFromObj(_configProperty, 'hbase-site', 'version1', this);
       this._recordHostOverrideFromObj(_configProperty, 'hbase-site', 'version1', this);
     }, this);
     }, this);
     return {type: 'hbase-site', tag: 'version1', properties: hbaseProperties};
     return {type: 'hbase-site', tag: 'version1', properties: hbaseProperties};
@@ -1508,7 +1508,7 @@ App.WizardStep8Controller = Em.Controller.extend({
     var configs = this.get('configs').filterProperty('filename', 'oozie-site.xml');
     var configs = this.get('configs').filterProperty('filename', 'oozie-site.xml');
     var oozieProperties = {};
     var oozieProperties = {};
     configs.forEach(function (_configProperty) {
     configs.forEach(function (_configProperty) {
-      oozieProperties[_configProperty.name] = _configProperty.value;
+      oozieProperties[_configProperty.name] = App.config.escapeXMLCharacters(_configProperty.value);
       this._recordHostOverrideFromObj(_configProperty, 'oozie-site', 'version1', this);
       this._recordHostOverrideFromObj(_configProperty, 'oozie-site', 'version1', this);
     }, this);
     }, this);
     var globals = this.get('content.serviceConfigProperties').filterProperty('id', 'puppet var');
     var globals = this.get('content.serviceConfigProperties').filterProperty('id', 'puppet var');
@@ -1537,7 +1537,7 @@ App.WizardStep8Controller = Em.Controller.extend({
     var configs = this.get('configs').filterProperty('filename', 'hive-site.xml');
     var configs = this.get('configs').filterProperty('filename', 'hive-site.xml');
     var hiveProperties = {};
     var hiveProperties = {};
     configs.forEach(function (_configProperty) {
     configs.forEach(function (_configProperty) {
-      hiveProperties[_configProperty.name] = _configProperty.value;
+      hiveProperties[_configProperty.name] = App.config.escapeXMLCharacters(_configProperty.value);
       this._recordHostOverrideFromObj(_configProperty, 'hive-site', 'version1', this);
       this._recordHostOverrideFromObj(_configProperty, 'hive-site', 'version1', this);
     }, this);
     }, this);
     var globals = this.get('content.serviceConfigProperties').filterProperty('id', 'puppet var');
     var globals = this.get('content.serviceConfigProperties').filterProperty('id', 'puppet var');
@@ -1563,7 +1563,7 @@ App.WizardStep8Controller = Em.Controller.extend({
     var configs = this.get('configs').filterProperty('filename', 'webhcat-site.xml');
     var configs = this.get('configs').filterProperty('filename', 'webhcat-site.xml');
     var webHCatProperties = {};
     var webHCatProperties = {};
     configs.forEach(function (_configProperty) {
     configs.forEach(function (_configProperty) {
-      webHCatProperties[_configProperty.name] = _configProperty.value;
+      webHCatProperties[_configProperty.name] = App.config.escapeXMLCharacters(_configProperty.value);
       this._recordHostOverrideFromObj(_configProperty, 'webhcat-site', 'version1', this);
       this._recordHostOverrideFromObj(_configProperty, 'webhcat-site', 'version1', this);
     }, this);
     }, this);
     return {type: 'webhcat-site', tag: 'version1', properties: webHCatProperties};
     return {type: 'webhcat-site', tag: 'version1', properties: webHCatProperties};

+ 38 - 1
ambari-web/app/utils/config.js

@@ -24,7 +24,44 @@ var configGroupsByTag = [];
 var globalPropertyToServicesMap = null;
 var globalPropertyToServicesMap = null;
 
 
 App.config = Em.Object.create({
 App.config = Em.Object.create({
-
+  /**
+   * XML characters which should be escaped in values
+   * http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Predefined_entities_in_XML
+   */
+  xmlEscapeMap: {
+    "&": "&amp;",
+    "<": "&lt;",
+    ">": "&gt;",
+    '"': '&quot;',
+    "'": '&apos;'
+  },
+  xmlUnEscapeMap: {
+    "&amp;": "&",
+    "&lt;": "<",
+    "&gt;": ">",
+    "&quot;": '"',
+    "&apos;": "'"
+  },
+  
+  /**
+   * Since values end up in XML files (core-sit.xml, etc.), certain
+   * XML sensitive characters should be escaped. If not we will have
+   * an invalid XML document, and services will fail to start. 
+   * 
+   * Special characters in XML are defined at
+   * http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Predefined_entities_in_XML
+   */
+  escapeXMLCharacters: function(value) {
+    var self = this;
+    // To prevent double/triple replacing '&gt;' to '&gt;gt;' to '&gt;gt;gt', we need
+    // to first unescape all XML chars, and then escape them again.
+    var newValue = String(value).replace(/(&amp;|&lt;|&gt;|&quot;|&apos;)/g, function (s) {
+      return self.xmlUnEscapeMap[s];
+    });
+    return String(newValue).replace(/[&<>"']/g, function (s) {
+      return self.xmlEscapeMap[s];
+    });
+  },
   preDefinedServiceConfigs: function(){
   preDefinedServiceConfigs: function(){
     var configs = this.get('preDefinedGlobalProperties');
     var configs = this.get('preDefinedGlobalProperties');
     var services = [];
     var services = [];