Browse Source

AMBARI-25934: Add support for Ambari Infra in Ambari Server Bigtop Stack (#3696)

jialiang 2 years ago
parent
commit
b97e1389b2
42 changed files with 3334 additions and 0 deletions
  1. 37 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/alerts.json
  2. 68 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/configuration/infra-solr-client-log4j.xml
  3. 334 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/configuration/infra-solr-env.xml
  4. 56 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/configuration/infra-solr-log4j.xml
  5. 153 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/configuration/infra-solr-security-json.xml
  6. 35 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/configuration/infra-solr-xml.xml
  7. 53 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/kerberos.json
  8. 208 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/metainfo.xml
  9. 298 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/collection.py
  10. BIN
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/collection.pyo
  11. 373 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/command_commons.py
  12. BIN
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/command_commons.pyo
  13. 171 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/infra_solr.py
  14. BIN
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/infra_solr.pyo
  15. 60 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/infra_solr_client.py
  16. BIN
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/infra_solr_client.pyo
  17. 62 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/migrate.py
  18. BIN
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/migrate.pyo
  19. 219 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/params.py
  20. BIN
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/params.pyo
  21. 48 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/service_check.py
  22. BIN
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/service_check.pyo
  23. 163 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/setup_infra_solr.py
  24. BIN
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/setup_infra_solr.pyo
  25. 40 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/status_params.py
  26. BIN
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/status_params.pyo
  27. 84 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/templates/infra-solr-security.json.j2
  28. 17 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/templates/infra-solr.conf.j2
  29. 26 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/templates/infra_solr_jaas.conf.j2
  30. 48 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/templates/input.config-ambari-infra.json.j2
  31. 108 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/properties/infra-solr-env.sh.j2
  32. 42 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/properties/solr-client-log4j.properties.j2
  33. 74 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/properties/solr-log4j2.xml.j2
  34. 122 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/properties/solr.xml.j2
  35. 34 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/quicklinks/quicklinks.json
  36. 7 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/role_command_order.json
  37. 129 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/service_advisor.py
  38. BIN
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/service_advisor.pyo
  39. 127 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/themes/directories.json
  40. 107 0
      ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/themes/theme.json
  41. 5 0
      ambari-server/src/main/resources/stacks/BIGTOP/3.2.0/properties/stack_features.json
  42. 26 0
      ambari-server/src/main/resources/stacks/BIGTOP/3.2.0/services/AMBARI_INFRA_SOLR/metainfo.xml

+ 37 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/alerts.json

@@ -0,0 +1,37 @@
+{
+  "AMBARI_INFRA_SOLR": {
+    "INFRA_SOLR": [
+      {
+        "name": "infra_solr",
+        "label": "Infra Solr Web UI",
+        "description": "This host-level alert is triggered if the Solr Cloud Instance is unreachable.",
+        "interval": 1,
+        "scope": "ANY",
+        "source": {
+          "type": "WEB",
+          "uri": {
+            "http": "{{infra-solr-env/infra_solr_port}}",
+            "https": "{{infra-solr-env/infra_solr_port}}",
+            "https_property": "{{infra-solr-env/infra_solr_ssl_enabled}}",
+            "https_property_value": "true",
+            "connection_timeout": 5.0,
+            "kerberos_keytab": "{{cluster-env/smokeuser_keytab}}",
+            "kerberos_principal": "{{cluster-env/smokeuser_principal_name}}",
+            "default_port": 8886
+          },
+          "reporting": {
+            "ok": {
+              "text": "HTTP {0} response in {2:.3f}s"
+            },
+            "warning": {
+              "text": "HTTP {0} response from {1} in {2:.3f}s ({3})"
+            },
+            "critical": {
+              "text": "Connection failed to {1} ({3})"
+            }
+          }
+        }
+      }
+    ]
+  }
+}

+ 68 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/configuration/infra-solr-client-log4j.xml

@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<!-- This is a special config file for properties used to monitor status of the service -->
+<configuration supports_adding_forbidden="true">
+  <!-- log4j.xml -->
+  <property>
+     <name>infra_client_log_maxfilesize</name>
+      <value>80</value>
+    <description>The maximum size of backup file before the log is rotated</description>
+    <display-name>Ambari-Infra Solr Client Log: backup file size</display-name>
+    <value-attributes>
+      <unit>MB</unit>
+    </value-attributes>
+    <on-ambari-upgrade add="true"/>
+   </property>
+   <property>
+    <name>infra_client_log_maxbackupindex</name>
+    <value>60</value>
+    <description>The number of backup files</description>
+    <display-name>Ambari-Infra Solr Client Log: # of backup files</display-name>
+    <value-attributes>
+      <type>int</type>
+      <minimum>0</minimum>
+    </value-attributes>
+    <on-ambari-upgrade add="true"/>
+  </property>
+  <property>
+    <name>infra_solr_client_log_dir</name>
+    <value>/var/log/ambari-infra-solr-client</value>
+    <description>Directory for Solr client logs</description>
+    <display-name>Infra Solr Client log dir</display-name>
+    <value-attributes>
+      <type>directory</type>
+    </value-attributes>
+    <on-ambari-upgrade add="false"/>
+  </property>
+  <property>
+    <name>content</name>
+    <display-name>log4j template</display-name>
+    <description>This is the jinja template for log4j.properties file for infra solr client</description>
+    <value/>
+    <property-type>VALUE_FROM_PROPERTY_FILE</property-type>
+    <value-attributes>
+      <property-file-name>solr-client-log4j.properties.j2</property-file-name>
+      <property-file-type>text</property-file-type>
+    </value-attributes>
+    <on-ambari-upgrade add="false"/>
+  </property>
+</configuration>

+ 334 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/configuration/infra-solr-env.xml

@@ -0,0 +1,334 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<!-- This is a special config file for properties used to monitor status of the service -->
+<configuration supports_adding_forbidden="true">
+  <property>
+    <name>infra_solr_port</name>
+    <value>8886</value>
+    <description>Solr port</description>
+    <display-name>Infra Solr port</display-name>
+    <on-ambari-upgrade add="false"/>
+  </property>
+  <property>
+    <name>infra_solr_jmx_port</name>
+    <value>18886</value>
+    <description>Solr JMX port</description>
+    <display-name>Infra Solr JMX port</display-name>
+    <on-ambari-upgrade add="false"/>
+  </property>
+  <property>
+    <name>infra_solr_pid_dir</name>
+    <value>/var/run/ambari-infra-solr</value>
+    <description>Solr Process ID Directory</description>
+    <display-name>Infra Solr pid dir</display-name>
+    <value-attributes>
+      <type>directory</type>
+    </value-attributes>
+    <on-ambari-upgrade add="false"/>
+  </property>
+  <property>
+    <name>infra_solr_log_dir</name>
+    <value>/var/log/ambari-infra-solr</value>
+    <description>Directory for Solr logs</description>
+    <display-name>Infra Solr log dir</display-name>
+    <value-attributes>
+      <type>directory</type>
+    </value-attributes>
+    <on-ambari-upgrade add="false"/>
+  </property>
+  <property>
+    <name>infra_solr_user</name>
+    <value>infra-solr</value>
+    <property-type>USER</property-type>
+    <description>Solr user</description>
+    <display-name>Infra Solr User</display-name>
+    <value-attributes>
+      <type>user</type>
+      <overridable>false</overridable>
+      <user-groups>
+        <property>
+          <type>cluster-env</type>
+          <name>user_group</name>
+        </property>
+      </user-groups>
+    </value-attributes>
+    <on-ambari-upgrade add="false"/>
+  </property>
+  <property>
+    <name>infra_solr_datadir</name>
+    <value>/var/lib/ambari-infra-solr/data</value>
+    <display-name>Infra Solr data dir</display-name>
+    <description>Directory for storting Solr index. Make sure you have enough disk space</description>
+    <value-attributes>
+      <type>directory</type>
+      <overridable>false</overridable>
+    </value-attributes>
+    <on-ambari-upgrade add="false"/>
+  </property>
+  <property>
+    <name>infra_solr_ssl_enabled</name>
+    <value>false</value>
+    <display-name>Enable SSL to Infra Solr</display-name>
+    <description>Enable ssl to Solr</description>
+    <value-attributes>
+      <type>boolean</type>
+    </value-attributes>
+    <on-ambari-upgrade add="false"/>
+  </property>
+  <property>
+    <name>infra_solr_truststore_location</name>
+    <value>/etc/security/serverKeys/infra.solr.trustStore.jks</value>
+    <display-name>Infra Solr trust store location</display-name>
+    <description>Location of the trust store file. (default value is not generated)</description>
+    <on-ambari-upgrade add="false"/>
+  </property>
+  <property>
+    <name>infra_solr_truststore_type</name>
+    <value>jks</value>
+    <display-name>Infra Solr trust store type</display-name>
+    <description>Type of the trust store file.</description>
+    <on-ambari-upgrade add="false"/>
+  </property>
+  <property>
+    <name>infra_solr_truststore_password</name>
+    <value>bigdata</value>
+    <property-type>PASSWORD</property-type>
+    <display-name>Infra Solr trust store password</display-name>
+    <description>Password to open the trust store file.</description>
+    <value-attributes>
+      <type>password</type>
+    </value-attributes>
+    <on-ambari-upgrade add="false"/>
+  </property>
+  <property>
+    <name>infra_solr_keystore_location</name>
+    <value>/etc/security/serverKeys/infra.solr.keyStore.jks</value>
+    <display-name>Infra Solr key store location</display-name>
+    <description>Location of the key store file. (default value is not generated)</description>
+    <on-ambari-upgrade add="false"/>
+  </property>
+  <property>
+    <name>infra_solr_keystore_type</name>
+    <value>jks</value>
+    <display-name>Infra Solr key store type</display-name>
+    <description>Type of the key store file.</description>
+    <on-ambari-upgrade add="false"/>
+  </property>
+  <property>
+    <name>infra_solr_keystore_password</name>
+    <value>bigdata</value>
+    <display-name>Infra Solr key store password</display-name>
+    <property-type>PASSWORD</property-type>
+    <description>Password to open the key store file.</description>
+    <value-attributes>
+      <type>password</type>
+    </value-attributes>
+    <on-ambari-upgrade add="false"/>
+  </property>
+  <property>
+    <name>infra_solr_znode</name>
+    <value>/infra-solr</value>
+    <description>Zookeeper znode, e.g: /ambari-solr</description>
+    <display-name>Infra Solr ZNode</display-name>
+    <value-attributes>
+      <overridable>false</overridable>
+    </value-attributes>
+    <on-ambari-upgrade add="false"/>
+  </property>
+  <property>
+    <name>infra_solr_minmem</name>
+    <value>1024</value>
+    <display-name>Infra Solr Minimum Heap Size</display-name>
+    <description>Solr minimum heap size e.g. 512m</description>
+    <value-attributes>
+      <type>int</type>
+      <minimum>512</minimum>
+      <maximum>32768</maximum>
+      <unit>MB</unit>
+      <increment-step>256</increment-step>
+    </value-attributes>
+    <on-ambari-upgrade add="false"/>
+  </property>
+  <property>
+    <name>infra_solr_maxmem</name>
+    <value>2048</value>
+    <display-name>Infra Solr Maximum Heap Size</display-name>
+    <description>Solr maximum heap size e.g. 512m</description>
+    <value-attributes>
+      <type>int</type>
+      <minimum>512</minimum>
+      <maximum>32768</maximum>
+      <unit>MB</unit>
+      <increment-step>256</increment-step>
+    </value-attributes>
+    <on-ambari-upgrade add="false"/>
+  </property>
+  <property>
+    <name>infra_solr_java_stack_size</name>
+    <value>1</value>
+    <display-name>Infra Solr Java Stack Size</display-name>
+    <description>Java Stack Size of Infra Solr (-Xss) in MB.</description>
+    <value-attributes>
+      <type>int</type>
+      <minimum>1</minimum>
+      <maximum>128</maximum>
+      <unit>MB</unit>
+      <increment-step>1</increment-step>
+    </value-attributes>
+    <on-ambari-upgrade add="true"/>
+  </property>
+  <property>
+    <name>infra_solr_jmx_enabled</name>
+    <value>false</value>
+    <display-name>Enable JMX</display-name>
+    <description>Set to true to activate the JMX RMI connector to allow remote JMX client applications to monitor the JVM hosting Solr
+    </description>
+    <value-attributes>
+      <type>boolean</type>
+    </value-attributes>
+    <on-ambari-upgrade add="true"/>
+  </property>
+  <property>
+    <name>infra_solr_kerberos_keytab</name>
+    <value>/etc/security/keytabs/infra_solr.service.keytab</value>
+    <display-name>Infra Solr keytab</display-name>
+    <description>The path to the Kerberos Keytab file containing service principal of the Infra Solr.</description>
+    <on-ambari-upgrade add="false"/>
+  </property>
+
+  <property>
+    <name>infra_solr_kerberos_principal</name>
+    <value>infra-solr</value>
+    <display-name>Infra Solr principal</display-name>
+    <description>The service principal for Infra Solr.</description>
+    <property-type>KERBEROS_PRINCIPAL</property-type>
+    <on-ambari-upgrade add="false"/>
+  </property>
+
+  <property>
+    <name>infra_solr_web_kerberos_keytab</name>
+    <value>/etc/security/keytabs/spnego.service.keytab</value>
+    <display-name>Infra Solr Http keytab</display-name>
+    <description>The path to the Kerberos Keytab file containing service principal of the Infra Solr.</description>
+    <on-ambari-upgrade add="false"/>
+  </property>
+
+  <property>
+    <name>infra_solr_web_kerberos_principal</name>
+    <value>HTTP/_HOST@EXAMPLE.COM</value>
+    <display-name>Infra Solr Http principal</display-name>
+    <description>The service principal for the Infra Solr.</description>
+    <property-type>KERBEROS_PRINCIPAL</property-type>
+    <on-ambari-upgrade add="false"/>
+  </property>
+
+  <property>
+    <name>infra_solr_zookeeper_quorum</name>
+    <value>{zookeeper_quorum}</value>
+    <display-name>Infra Solr Znode</display-name>
+    <description>Placeholder for Infra Solr Zookeeper connection string. (Use the cluster one by default, you can override this with a custom one if ZK needs to be external)</description>
+    <on-ambari-upgrade add="true"/>
+  </property>
+
+  <property>
+    <name>infra_solr_zookeeper_external_principal</name>
+    <value>zookeeper/_HOST@EXAMPLE.COM</value>
+    <display-name>External ZK principal</display-name>
+    <description>The kerberos service principal name for external ZooKeeper.</description>
+    <on-ambari-upgrade add="true"/>
+  </property>
+
+  <property>
+    <name>infra_solr_zookeeper_external_enabled</name>
+    <value>false</value>
+    <display-name>Enable External ZK</display-name>
+    <description>Enable external ZooKeeper. If the Solr is secure, the external ZK should be secure as well.</description>
+    <value-attributes>
+      <type>boolean</type>
+    </value-attributes>
+    <on-ambari-upgrade add="true"/>
+  </property>
+
+  <property>
+    <name>infra_solr_kerberos_name_rules</name>
+    <value>DEFAULT</value>
+    <display-name>Infra Solr Kerberos name rules</display-name>
+    <description>Kerberos name rules for Spnego</description>
+    <value-attributes>
+      <overridable>false</overridable>
+    </value-attributes>
+    <on-ambari-upgrade add="false"/>
+  </property>
+
+  <property>
+    <name>infra_solr_user_nofile_limit</name>
+    <value>128000</value>
+    <description>Max open files limit setting for infra-solr user.</description>
+    <on-ambari-upgrade add="true"/>
+  </property>
+  <property>
+    <name>infra_solr_user_nproc_limit</name>
+    <value>65536</value>
+    <description>Max number of processes limit setting for infra-solr user.</description>
+    <on-ambari-upgrade add="true"/>
+  </property>
+
+  <property>
+    <name>infra_solr_extra_java_opts</name>
+    <value></value>
+    <display-name>Infra Solr extra java options</display-name>
+    <description>Extra Solr java options (e.g.: -Dproperty=value), that will be added to SOLR_OPTS environment variable</description>
+    <value-attributes>
+      <empty-value-valid>true</empty-value-valid>
+    </value-attributes>
+    <on-ambari-upgrade add="true"/>
+  </property>
+
+  <property>
+    <name>infra_solr_gc_log_opts</name>
+    <value>-verbose:gc -XX:+PrintHeapAtGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=15 -XX:GCLogFileSize=200M</value>
+    <display-name>Infra Solr GC log options</display-name>
+    <description>Infra Solr GC log options</description>
+    <on-ambari-upgrade add="true"/>
+  </property>
+  <property>
+    <name>infra_solr_gc_tune</name>
+    <value>-XX:NewRatio=3 -XX:SurvivorRatio=4 -XX:TargetSurvivorRatio=90 -XX:MaxTenuringThreshold=8 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:ConcGCThreads=4 -XX:ParallelGCThreads=4 -XX:+CMSScavengeBeforeRemark -XX:PretenureSizeThreshold=64m -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=50 -XX:CMSMaxAbortablePrecleanTime=6000 -XX:+CMSParallelRemarkEnabled -XX:+ParallelRefProcEnabled</value>
+    <display-name>Infra Solr GC Tune</display-name>
+    <description>Infra Solr GC Tune</description>
+    <on-ambari-upgrade add="true"/>
+  </property>
+
+  <!-- infra-solr-env.sh -->
+  <property>
+    <name>content</name>
+    <display-name>infra-solr-env template</display-name>
+    <description>This is the jinja template for infra-solr-env.sh file</description>
+    <value/>
+    <property-type>VALUE_FROM_PROPERTY_FILE</property-type>
+    <value-attributes>
+      <property-file-name>infra-solr-env.sh.j2</property-file-name>
+      <property-file-type>text</property-file-type>
+    </value-attributes>
+    <on-ambari-upgrade add="false" update="true"/>
+  </property>
+</configuration>

+ 56 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/configuration/infra-solr-log4j.xml

@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<configuration supports_adding_forbidden="true">
+  <property>
+    <name>infra_log_maxfilesize</name>
+    <value>10</value>
+    <description>The maximum size of backup file before the log is rotated</description>
+    <display-name>Ambari Infra Log: backup file size</display-name>
+    <value-attributes>
+      <unit>MB</unit>
+    </value-attributes>
+    <on-ambari-upgrade add="true"/>
+  </property>
+  <property>
+    <name>infra_log_maxbackupindex</name>
+    <value>9</value>
+    <description>The number of backup files</description>
+    <display-name>Ambari Infra Log: # of backup files</display-name>
+    <value-attributes>
+      <type>int</type>
+      <minimum>0</minimum>
+    </value-attributes>
+    <on-ambari-upgrade add="true"/>
+  </property>
+  <property>
+    <name>content</name>
+    <display-name>infra-solr-log4j template</display-name>
+    <description>This is the jinja template for log4j2.xml</description>
+    <value/>
+    <property-type>VALUE_FROM_PROPERTY_FILE</property-type>
+    <value-attributes>
+      <property-file-name>solr-log4j2.xml.j2</property-file-name>
+      <property-file-type>text</property-file-type>
+    </value-attributes>
+    <on-ambari-upgrade add="false"/>
+  </property>
+</configuration>

+ 153 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/configuration/infra-solr-security-json.xml

@@ -0,0 +1,153 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<!-- This is a special config file for properties used to monitor status of the service -->
+<configuration supports_adding_forbidden="true">
+  <property>
+    <name>infra_solr_ranger_audit_service_users</name>
+    <display-name>Ranger audit service users</display-name>
+    <value>{default_ranger_audit_users}</value>
+    <description>
+      List of comma separated kerberos service users who can write into ranger audit collections if the cluster is
+      secure. (atlas and rangeradmin supported by default)
+      Change values in that case of custom values are used for kerberos principals. (default_ranger_audit_users is
+      resolved ranger-*-audit/xasecure.audit.jaas.Client.option.principal,
+      by default namenode, hbase, hive knox, kafka, ranger kms and nifi are supported, to change it you can edit the
+      security content,
+      or add a new username next to the default value, e.g.: {default_ranger_audit_users},customuser)
+    </description>
+    <depends-on>
+      <property>
+        <type>ranger-hdfs-audit</type>
+        <name>xasecure.audit.jaas.Client.option.principal</name>
+      </property>
+      <property>
+        <type>ranger-hbase-audit</type>
+        <name>xasecure.audit.jaas.Client.option.principal</name>
+      </property>
+      <property>
+        <type>ranger-hive-audit</type>
+        <name>xasecure.audit.jaas.Client.option.principal</name>
+      </property>
+      <property>
+        <type>ranger-knox-audit</type>
+        <name>xasecure.audit.jaas.Client.option.principal</name>
+      </property>
+      <property>
+        <type>ranger-kafka-audit</type>
+        <name>xasecure.audit.jaas.Client.option.principal</name>
+      </property>
+      <property>
+        <type>ranger-kms-audit</type>
+        <name>xasecure.audit.jaas.Client.option.principal</name>
+      </property>
+      <property>
+        <type>ranger-storm-audit</type>
+        <name>xasecure.audit.jaas.Client.option.principal</name>
+      </property>
+      <property>
+        <type>ranger-yarn-audit</type>
+        <name>xasecure.audit.jaas.Client.option.principal</name>
+      </property>
+      <property>
+        <type>ranger-nifi-audit</type>
+        <name>xasecure.audit.jaas.Client.option.principal</name>
+      </property>
+      <property>
+        <type>application-properties</type>
+        <name>atlas.authentication.principal</name>
+      </property>
+      <property>
+        <type>ranger-admin-site</type>
+        <name>ranger.admin.kerberos.principal</name>
+      </property>
+    </depends-on>
+    <on-ambari-upgrade add="true"/>
+  </property>
+  <property>
+    <name>infra_solr_role_ranger_admin</name>
+    <display-name>Ranger admin role</display-name>
+    <value>ranger_admin_user</value>
+    <description>Ranger admin role, it allows users to create collection, and perform any action on ranger audit collection.</description>
+    <on-ambari-upgrade add="true"/>
+  </property>
+  <property>
+    <name>infra_solr_role_ranger_audit</name>
+    <display-name>Ranger audit role</display-name>
+    <value>ranger_audit_user</value>
+    <description>Ranger audit role, it allows users to perform any action on ranger audit collection.</description>
+    <on-ambari-upgrade add="true"/>
+  </property>
+  <property>
+    <name>infra_solr_role_atlas</name>
+    <display-name>Atlas role</display-name>
+    <value>atlas_user</value>
+    <description>Atlas role, it allows users to create collection, and perform any action on atlas collections.</description>
+    <on-ambari-upgrade add="true"/>
+  </property>
+  <property>
+    <name>infra_solr_role_logsearch</name>
+    <display-name>Log Search role</display-name>
+    <value>logsearch_user</value>
+    <description>Log Search role, it allows users to create collection, and perform any action on Log Search collections.</description>
+    <on-ambari-upgrade add="true"/>
+  </property>
+  <property>
+    <name>infra_solr_role_logfeeder</name>
+    <display-name>Log Feeder role</display-name>
+    <value>logfeeder_user</value>
+    <description>Log Feeder role, it allows users to perform any action on Log Search collections.</description>
+    <on-ambari-upgrade add="true"/>
+  </property>
+  <property>
+    <name>infra_solr_role_dev</name>
+    <display-name>Dev role</display-name>
+    <value>dev</value>
+    <description>Dev role, it allows to perform any read action on any collection.</description>
+    <on-ambari-upgrade add="true"/>
+  </property>
+  <property>
+    <name>infra_solr_security_manually_managed</name>
+    <value>false</value>
+    <display-name>Manually Managed</display-name>
+    <description>Manage /security.json manually (Service start wont override /security.json)</description>
+    <value-attributes>
+      <type>boolean</type>
+    </value-attributes>
+    <on-ambari-upgrade add="true"/>
+  </property>
+  <property>
+    <name>content</name>
+    <display-name>Custom security.json template</display-name>
+    <description>
+      This is the jinja template for custom security.json file on the solr znode
+      (only used if the cluster is secure and this property overrides the security.json which generated during solr
+      start).
+    </description>
+    <value/>
+    <value-attributes>
+      <type>content</type>
+      <show-property-name>false</show-property-name>
+      <empty-value-valid>true</empty-value-valid>
+    </value-attributes>
+    <on-ambari-upgrade add="true"/>
+  </property>
+</configuration>

+ 35 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/configuration/infra-solr-xml.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<configuration supports_adding_forbidden="true">
+  <property>
+    <name>content</name>
+    <display-name>infra-solr-xml template</display-name>
+    <description>This is the jinja template for Ambari Infrastructure solr.xml file</description>
+    <value/>
+    <property-type>VALUE_FROM_PROPERTY_FILE</property-type>
+    <value-attributes>
+      <property-file-name>solr.xml.j2</property-file-name>
+      <property-file-type>xml</property-file-type>
+    </value-attributes>
+    <on-ambari-upgrade add="false" update="true"/>
+  </property>
+</configuration>

+ 53 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/kerberos.json

@@ -0,0 +1,53 @@
+{
+  "services": [
+    {
+      "name": "AMBARI_INFRA_SOLR",
+      "identities": [
+        {
+          "name": "ambari_infra_smokeuser",
+          "reference": "/smokeuser"
+        },
+        {
+          "name": "ambari_infra_spnego",
+          "reference": "/spnego",
+          "principal": {
+            "configuration": "infra-solr-env/infra_solr_web_kerberos_principal"
+          },
+          "keytab": {
+            "configuration": "infra-solr-env/infra_solr_web_kerberos_keytab"
+          }
+        }
+      ],
+      "components": [
+        {
+          "name": "INFRA_SOLR",
+          "identities": [
+            {
+              "name": "infra-solr",
+              "principal": {
+                "value": "infra-solr/_HOST@${realm}",
+                "type": "service",
+                "configuration": "infra-solr-env/infra_solr_kerberos_principal"
+              },
+              "keytab": {
+                "file": "${keytab_dir}/ambari-infra-solr.service.keytab",
+                "owner": {
+                  "name": "${infra-solr-env/infra_solr_user}",
+                  "access": "r"
+                },
+                "group": {
+                  "name": "${cluster-env/user_group}",
+                  "access": ""
+                },
+                "configuration": "infra-solr-env/infra_solr_kerberos_keytab"
+              }
+            }
+          ]
+        },
+        {
+          "name": "INFRA_SOLR_CLIENT"
+        }
+      ]
+    }
+  ]
+}

+ 208 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/metainfo.xml

@@ -0,0 +1,208 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<metainfo>
+  <schemaVersion>2.0</schemaVersion>
+  <services>
+    <service>
+      <name>AMBARI_INFRA_SOLR</name>
+      <displayName>Infra Solr</displayName>
+      <comment>Core shared service used by Ambari managed components.</comment>
+      <version>3.0.0</version>
+      <components>
+        <component>
+          <name>INFRA_SOLR</name>
+          <timelineAppid>infra-solr</timelineAppid>
+          <displayName>Infra Solr Instance</displayName>
+          <category>MASTER</category>
+          <cardinality>1+</cardinality>
+          <versionAdvertised>false</versionAdvertised>
+          <commandScript>
+            <script>scripts/infra_solr.py</script>
+            <scriptType>PYTHON</scriptType>
+            <timeout>1800</timeout>
+          </commandScript>
+          <logs>
+            <log>
+              <logId>infra_solr</logId>
+              <primary>true</primary>
+            </log>
+          </logs>
+          <customCommands>
+            <customCommand>
+              <name>BACKUP</name>
+              <hidden>true</hidden>
+              <commandScript>
+                <script>scripts/infra_solr.py</script>
+                <scriptType>PYTHON</scriptType>
+                <timeout>36000</timeout>
+                <background>true</background>
+              </commandScript>
+            </customCommand>
+            <customCommand>
+              <name>RESTORE</name>
+              <hidden>true</hidden>
+              <commandScript>
+                <script>scripts/infra_solr.py</script>
+                <scriptType>PYTHON</scriptType>
+                <background>true</background>
+                <timeout>36000</timeout>
+              </commandScript>
+            </customCommand>
+            <customCommand>
+              <name>MIGRATE</name>
+              <hidden>true</hidden>
+              <commandScript>
+                <script>scripts/infra_solr.py</script>
+                <scriptType>PYTHON</scriptType>
+                <timeout>36000</timeout>
+                <background>true</background>
+              </commandScript>
+            </customCommand>
+            <customCommand>
+              <name>UPGRADE_SOLR_INSTANCE</name>
+              <hidden>true</hidden>
+              <commandScript>
+                <script>scripts/infra_solr.py</script>
+                <scriptType>PYTHON</scriptType>
+                <timeout>1200</timeout>
+              </commandScript>
+            </customCommand>
+          </customCommands>
+          <dependencies>
+            <dependency>
+              <name>AMBARI_INFRA_SOLR/INFRA_SOLR_CLIENT</name>
+              <scope>host</scope>
+              <auto-deploy>
+                <enabled>true</enabled>
+              </auto-deploy>
+            </dependency>
+
+            <dependency>
+              <name>ZOOKEEPER/ZOOKEEPER_SERVER</name>
+              <scope>cluster</scope>
+              <auto-deploy>
+                <enabled>true</enabled>
+              </auto-deploy>
+            </dependency>
+
+          </dependencies>
+          <configuration-dependencies>
+            <config-type>infra-solr-env</config-type>
+            <config-type>infra-solr-xml</config-type>
+            <config-type>infra-solr-log4j</config-type>
+            <config-type>infra-solr-security-json</config-type>
+          </configuration-dependencies>
+        </component>
+
+        <component>
+          <name>INFRA_SOLR_CLIENT</name>
+          <displayName>Infra Solr Client</displayName>
+          <category>CLIENT</category>
+          <cardinality>0+</cardinality>
+          <versionAdvertised>false</versionAdvertised>
+          <commandScript>
+            <script>scripts/infra_solr_client.py</script>
+            <scriptType>PYTHON</scriptType>
+          </commandScript>
+          <customCommands>
+            <customCommand>
+              <name>UPGRADE_SOLR_CLIENT</name>
+              <hidden>true</hidden>
+              <commandScript>
+                <script>scripts/infra_solr_client.py</script>
+                <scriptType>PYTHON</scriptType>
+                <timeout>3600</timeout>
+              </commandScript>
+            </customCommand>
+          </customCommands>
+          <configFiles>
+            <configFile>
+              <type>env</type>
+              <fileName>log4j.properties</fileName>
+              <dictionaryName>infra-solr-client-log4j</dictionaryName>
+            </configFile>
+          </configFiles>
+          <configuration-dependencies>
+            <config-type>infra-solr-client-log4j</config-type>
+          </configuration-dependencies>
+        </component>
+
+      </components>
+
+      <osSpecifics>
+        <osSpecific>
+          <osFamily>redhat7,amazonlinux2,redhat6,suse11,suse12</osFamily>
+          <packages>
+            <package>
+              <name>ambari-infra-solr-client</name>
+              <skipUpgrade>true</skipUpgrade>
+            </package>
+            <package>
+              <name>ambari-infra-solr</name>
+              <condition>should_install_infra_solr</condition>
+              <skipUpgrade>true</skipUpgrade>
+            </package>
+          </packages>
+        </osSpecific>
+        <osSpecific>
+          <osFamily>debian7,debian9,ubuntu12,ubuntu14,ubuntu16,ubuntu18</osFamily>
+          <packages>
+            <package>
+              <name>ambari-infra-solr-client</name>
+              <skipUpgrade>true</skipUpgrade>
+            </package>
+            <package>
+              <name>ambari-infra-solr</name>
+              <condition>should_install_infra_solr</condition>
+              <skipUpgrade>true</skipUpgrade>
+            </package>
+          </packages>
+        </osSpecific>
+      </osSpecifics>
+
+      <commandScript>
+        <script>scripts/service_check.py</script>
+        <scriptType>PYTHON</scriptType>
+        <timeout>300</timeout>
+      </commandScript>
+
+      <requiredServices>
+        <service>ZOOKEEPER</service>
+      </requiredServices>
+
+      <themes>
+        <theme>
+          <fileName>theme.json</fileName>
+          <default>true</default>
+        </theme>
+        <theme>
+          <fileName>directories.json</fileName>
+          <default>true</default>
+        </theme>
+      </themes>
+
+      <quickLinksConfigurations>
+        <quickLinksConfiguration>
+          <fileName>quicklinks.json</fileName>
+          <default>true</default>
+        </quickLinksConfiguration>
+      </quickLinksConfigurations>
+
+    </service>
+  </services>
+</metainfo>

+ 298 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/collection.py

@@ -0,0 +1,298 @@
+"""
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+"""
+import os
+import time
+from resource_management.core.logger import Logger
+from resource_management.core.resources.system import Directory, Execute, File
+from resource_management.libraries.functions.format import format
+from resource_management.libraries.functions import solr_cloud_util
+from resource_management.libraries.resources.properties_file import PropertiesFile
+
+def backup_collection(env):
+  """
+  Backup collections using replication API (as Solr Cloud Backup API is not available in Solr 5)
+  If the cluster is not kerberized, it will be needed to resolve ip addresses to hostnames (as SOLR_HOST=`hostname -f` is not used by default in infra-solr-env)
+  """
+  import params, command_commons
+  env.set_params(command_commons)
+
+  Directory(command_commons.index_location,
+            mode=0755,
+            cd_access='a',
+            create_parents=True,
+            owner=params.infra_solr_user,
+            group=params.user_group
+            )
+
+  Logger.info(format("Backup Solr Collection {collection} to {index_location}"))
+
+  host_core_map = command_commons.solr_backup_host_cores_map
+
+  host_or_ip = params.hostname
+  # IP resolve - for unsecure cluster
+  host_ip_pairs = {}
+  if not params.security_enabled:
+    keys = host_core_map.keys()
+    for key in keys:
+      if command_commons.is_ip(key):
+        resolved_hostname = command_commons.resolve_ip_to_hostname(key)
+        host_ip_pairs[resolved_hostname] = key
+
+  if params.hostname in host_ip_pairs:
+    host_or_ip = host_ip_pairs[params.hostname]
+
+  cores = host_core_map[host_or_ip] if host_or_ip in host_core_map else []
+
+  for core in cores:
+    if core in command_commons.skip_cores:
+      Logger.info(format("Core '{core}' is filtered out."))
+      continue
+    solr_request_path = format("{core}/replication?command=BACKUP&location={index_location}&name={core}&wt=json")
+    backup_api_cmd = command_commons.create_solr_api_request_command(solr_request_path)
+
+    Execute(backup_api_cmd, user=params.infra_solr_user, logoutput=True)
+
+    if command_commons.request_async is False:
+      Logger.info("Sleep 5 seconds to wait until the backup request is executed.")
+      time.sleep(5)
+      Logger.info("Check backup status ...")
+      solr_status_request_path = format("{core}/replication?command=details&wt=json")
+      status_check_json_output = format("{index_location}/backup_status.json")
+      status_check_cmd = command_commons.create_solr_api_request_command(solr_status_request_path,
+                                                                         status_check_json_output)
+      command_commons.snapshot_status_check(status_check_cmd, status_check_json_output, core, True,
+                                            log_output=command_commons.log_output, tries=command_commons.request_tries,
+                                            time_interval=command_commons.request_time_interval)
+      snapshot_folder=format("{index_location}/snapshot.{core}")
+      if command_commons.check_folder_exists(snapshot_folder):
+        command_commons.check_folder_until_size_not_changes(snapshot_folder)
+
+
+def restore_collection(env):
+  """
+  Restore collections - by copying snapshots with backup_* prefix, then remove old one and remove backup_* prefixes from the folder names.
+  """
+  import params, command_commons
+  env.set_params(command_commons)
+
+  if command_commons.solr_num_shards == 0:
+    raise Exception(format("The 'solr_shards' command parameter is required to set."))
+
+  if not command_commons.solr_restore_config_set:
+    raise Exception(format("The 'solr_restore_config_set' command parameter is required to set."))
+
+  Logger.info("Original core / host map: " + str(command_commons.solr_backup_core_host_map))
+  Logger.info("New core / host map: " + str(command_commons.solr_restore_core_host_map))
+
+  original_core_host_pairs = command_commons.sort_core_host_pairs(command_commons.solr_backup_core_host_map)
+  new_core_host_pairs = command_commons.sort_core_host_pairs(command_commons.solr_restore_core_host_map)
+
+  core_pairs = command_commons.create_core_pairs(original_core_host_pairs, new_core_host_pairs)
+  Logger.info("Generated core pairs: " + str(core_pairs))
+
+  Logger.info(format("Remove write.lock files from folder '{index_location}'"))
+  for write_lock_file in command_commons.get_files_by_pattern(format("{index_location}"), 'write.lock'):
+    File(write_lock_file, action="delete")
+
+  Logger.info(format("Restore Solr Collection {collection} from {index_location} ..."))
+
+  if command_commons.collection in ["ranger_audits", "history", "hadoop_logs", "audit_logs",
+                                    "vertex_index", "edge_index",
+                                    "fulltext_index"]:  # Make sure ambari wont delete an important collection
+    raise Exception(format(
+      "Selected collection for restore is: {collection}. It is not recommended to restore on default collections."))
+
+  hdfs_cores_on_host=[]
+
+  for core_pair in core_pairs:
+    src_core = core_pair['src_core']
+    target_core = core_pair['target_core']
+
+    if src_core in command_commons.skip_cores:
+      Logger.info(format("Core '{src_core}' (src) is filtered out."))
+      continue
+    elif target_core in command_commons.skip_cores:
+      Logger.info(format("Core '{target_core}' (target) is filtered out."))
+      continue
+
+    core_data = command_commons.solr_restore_core_data
+    only_if_cmd = format("test -d {index_location}/snapshot.{src_core}")
+    core_root_dir = format("{solr_datadir}/backup_{target_core}")
+    core_root_without_backup_dir = format("{solr_datadir}/{target_core}")
+
+    if command_commons.solr_hdfs_path:
+      Directory([core_root_dir],
+                mode=0755,
+                cd_access='a',
+                create_parents=True,
+                owner=params.infra_solr_user,
+                group=params.user_group,
+                only_if=only_if_cmd
+                )
+    else:
+      Directory([format("{core_root_dir}/data/index"),
+                 format("{core_root_dir}/data/tlog"),
+                 format("{core_root_dir}/data/snapshot_metadata")],
+                mode=0755,
+                cd_access='a',
+                create_parents=True,
+                owner=params.infra_solr_user,
+                group=params.user_group,
+                only_if=only_if_cmd
+                )
+
+    core_details = core_data[target_core]['properties']
+    core_properties = {}
+    core_properties['numShards'] = core_details['numShards']
+    core_properties['collection.configName'] = command_commons.solr_restore_config_set
+    core_properties['name'] = target_core
+    core_properties['replicaType'] = core_details['replicaType']
+    core_properties['collection'] = command_commons.collection
+    if command_commons.solr_hdfs_path:
+      core_properties['coreNodeName'] = 'backup_' + core_details['coreNodeName']
+    else:
+      core_properties['coreNodeName'] = core_details['coreNodeName']
+    core_properties['shard'] = core_details['shard']
+    if command_commons.solr_hdfs_path:
+      hdfs_solr_node_folder=command_commons.solr_hdfs_path + format("/backup_{collection}/") + core_details['coreNodeName']
+      source_folder=format("{index_location}/snapshot.{src_core}/")
+      if command_commons.check_folder_exists(source_folder):
+        hdfs_cores_on_host.append(target_core)
+        command_commons.HdfsResource(format("{hdfs_solr_node_folder}/data/index/"),
+                                   type="directory",
+                                   action="create_on_execute",
+                                   source=source_folder,
+                                   owner=params.infra_solr_user,
+                                   mode=0755,
+                                   recursive_chown=True,
+                                   recursive_chmod=True
+                                   )
+        command_commons.HdfsResource(format("{hdfs_solr_node_folder}/data/tlog"),
+                                   type="directory",
+                                   action="create_on_execute",
+                                   owner=params.infra_solr_user,
+                                   mode=0755
+                                   )
+        command_commons.HdfsResource(format("{hdfs_solr_node_folder}/data/snapshot_metadata"),
+                                   type="directory",
+                                   action="create_on_execute",
+                                   owner=params.infra_solr_user,
+                                   mode=0755
+                                   )
+    else:
+      copy_cmd = format("cp -r {index_location}/snapshot.{src_core}/* {core_root_dir}/data/index/") if command_commons.solr_keep_backup \
+        else format("mv {index_location}/snapshot.{src_core}/* {core_root_dir}/data/index/")
+      Execute(
+        copy_cmd, only_if=only_if_cmd,
+        user=params.infra_solr_user,
+        logoutput=True
+      )
+
+    PropertiesFile(
+      core_root_dir + '/core.properties',
+      properties=core_properties,
+      owner=params.infra_solr_user,
+      group=params.user_group,
+      mode=0644,
+      only_if=only_if_cmd
+    )
+
+  Execute(format("rm -rf {solr_datadir}/{collection}*"),
+          user=params.infra_solr_user,
+          logoutput=True)
+  for core_pair in core_pairs:
+    src_core = core_pair['src_core']
+    src_host = core_pair['src_host']
+    target_core = core_pair['target_core']
+
+    if src_core in command_commons.skip_cores:
+      Logger.info(format("Core '{src_core}' (src) is filtered out."))
+      continue
+    elif target_core in command_commons.skip_cores:
+      Logger.info(format("Core '{target_core}' (target) is filtered out."))
+      continue
+
+    if os.path.exists(format("{index_location}/snapshot.{src_core}")):
+      data_to_save = {}
+      host_core_data=command_commons.solr_restore_core_data
+      core_details=host_core_data[target_core]['properties']
+      core_node=core_details['coreNodeName']
+      data_to_save['core']=target_core
+      data_to_save['core_node']=core_node
+      data_to_save['old_host']=core_pair['target_host']
+      data_to_save['new_host']=src_host
+      if command_commons.solr_hdfs_path:
+        data_to_save['new_core_node']="backup_" + core_node
+      else:
+        data_to_save['new_core_node']=core_node
+
+      command_commons.write_core_file(target_core, data_to_save)
+      jaas_file = params.infra_solr_jaas_file if params.security_enabled else None
+      core_json_location = format("{index_location}/{target_core}.json")
+      znode_json_location = format("/restore_metadata/{collection}/{target_core}.json")
+      solr_cloud_util.copy_solr_znode_from_local(params.zookeeper_quorum, params.infra_solr_znode, params.java64_home, jaas_file, core_json_location, znode_json_location)
+
+    core_root_dir = format("{solr_datadir}/backup_{target_core}")
+    core_root_without_backup_dir = format("{solr_datadir}/{target_core}")
+
+    if command_commons.solr_hdfs_path:
+      if target_core in hdfs_cores_on_host:
+
+        Logger.info(format("Core data '{target_core}' is located on this host, processing..."))
+        host_core_data=command_commons.solr_restore_core_data
+        core_details=host_core_data[target_core]['properties']
+
+        core_node=core_details['coreNodeName']
+        collection_core_dir=command_commons.solr_hdfs_path + format("/{collection}/{core_node}")
+        backup_collection_core_dir=command_commons.solr_hdfs_path + format("/backup_{collection}/{core_node}")
+        command_commons.HdfsResource(collection_core_dir,
+                               type="directory",
+                               action="delete_on_execute",
+                               owner=params.infra_solr_user
+                               )
+        if command_commons.check_hdfs_folder_exists(backup_collection_core_dir):
+          collection_backup_core_dir=command_commons.solr_hdfs_path + format("/{collection}/backup_{core_node}")
+          command_commons.move_hdfs_folder(backup_collection_core_dir, collection_backup_core_dir)
+      else:
+        Logger.info(format("Core data '{target_core}' is not located on this host, skipping..."))
+
+    Execute(
+      format("mv {core_root_dir} {core_root_without_backup_dir}"),
+      user=params.infra_solr_user,
+      logoutput=True,
+      only_if=format("test -d {core_root_dir}")
+    )
+
+    Directory(
+      [format("{core_root_without_backup_dir}")],
+      mode=0755,
+      cd_access='a',
+      create_parents=True,
+      owner=params.infra_solr_user,
+      group=params.user_group,
+      recursive_ownership=True,
+      only_if=format("test -d {core_root_without_backup_dir}")
+    )
+
+    if command_commons.solr_hdfs_path and not command_commons.solr_keep_backup:
+      only_if_cmd = format("test -d {index_location}/snapshot.{src_core}")
+      Directory(format("{index_location}/snapshot.{src_core}"),
+            action="delete",
+            only_if=only_if_cmd,
+            owner=params.infra_solr_user)

BIN
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/collection.pyo


+ 373 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/command_commons.py

@@ -0,0 +1,373 @@
+"""
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+"""
+import fnmatch
+import json
+import os
+import socket
+import time
+import traceback
+from resource_management.core.logger import Logger
+from resource_management.core.resources.system import Execute, File
+from resource_management.core.shell import call
+from resource_management.libraries.functions.default import default
+from resource_management.libraries.functions.format import format
+from resource_management.libraries.resources.hdfs_resource import HdfsResource
+
+import params
+
+index_helper_script = '/usr/lib/ambari-infra-solr-client/solrIndexHelper.sh'
+
+# folder location which contains the snapshot/core folder
+index_location = default("/commandParams/solr_index_location", None)
+
+# index version (available index versions: 6.6.2 and 7.7.0, first one is used by default)
+index_version = default("/commandParams/solr_index_version", '6.6.2')
+
+# if this flag is false, skip upgrade if the version is proper, you can force to re-run the tool with setting the flag to true
+force = default("/commandParams/solr_index_upgrade_force", False)
+
+# if this flag is true, then it will generate specific folder for every backup with a hostname suffix
+# where "." chars replaced with "_"(e.g.: /my/path/backup_locationc7301_ambari_apache_org), that can be useful if different
+# hosts share the same filesystem where the backup is stored.
+shared_fs = default("/commandParams/solr_shared_fs", False)
+
+# set verbose log for index migration (default: true)
+debug = default("/commandParams/solr_migrate_debug", True)
+
+# used for filtering folders in backup location (like: if the filter is ranger, that will include snapshot.ranger folder but won't include snapshot.hadoop_logs)
+core_filter = default("/commandParams/solr_core_filter", None)
+
+# used to filer out comma separated cores - can be useful if backup/resotre failed in some point
+skip_cores = default("/commandParams/solr_skip_cores", "").split(",")
+
+# delete write.lock file at the start of lucene index migration process
+delete_lock_on_start = default("/commandParams/solr_delete_lock_on_start", True)
+# if it used, then core filter will be used with snapshot.* folder pattern
+backup_mode = default("/commandParams/solr_migrate_backup", True)
+
+log_output = default("/commandParams/solr_migrate_logoutput", True)
+# Solr colleection name (used for DELETE/BACKUP/RESTORE)
+collection = default("/commandParams/solr_collection", "ranger_audits")
+# it will be used in the snapshot name, if it's ranger, the snapshot folder will be snapshot.ranger
+backup_name = default("/commandParams/solr_backup_name", "ranger")
+
+request_async = default("/commandParams/solr_request_async", False)
+request_tries = int(default("/commandParams/solr_request_tries", 30))
+request_time_interval = int(default("/commandParams/solr_request_time_interval", 5))
+
+check_hosts_default = True if params.security_enabled else False
+check_hosts = default("/commandParams/solr_check_hosts", check_hosts_default)
+
+solr_protocol = "https" if params.infra_solr_ssl_enabled else "http"
+solr_port = format("{params.infra_solr_port}")
+solr_base_url = format("{solr_protocol}://{params.hostname}:{params.infra_solr_port}/solr")
+solr_datadir = params.infra_solr_datadir
+
+solr_keep_backup=default("/commandParams/solr_keep_backup", False)
+
+solr_num_shards = int(default("/commandParams/solr_shards", "0"))
+
+solr_hdfs_path=default("/commandParams/solr_hdfs_path", None)
+
+solr_backup_host_cores_map = json.loads(default("/commandParams/solr_backup_host_cores_map", "{}"))
+solr_backup_core_host_map = json.loads(default("/commandParams/solr_backup_core_host_map", "{}"))
+solr_restore_host_cores_map = json.loads(default("/commandParams/solr_restore_host_cores_map", "{}"))
+solr_restore_core_host_map = json.loads(default("/commandParams/solr_restore_core_host_map", "{}"))
+solr_restore_core_data = json.loads(default("/commandParams/solr_restore_core_data", "{}"))
+solr_restore_config_set = default("/commandParams/solr_restore_config_set", None)
+
+keytab = None
+principal = None
+if params.security_enabled:
+  keytab = params.infra_solr_kerberos_keytab
+  principal = params.infra_solr_kerberos_principal
+
+if solr_hdfs_path:
+
+  import functools
+  from resource_management.libraries.functions import conf_select
+  from resource_management.libraries.functions import stack_select
+  from resource_management.libraries.functions import get_klist_path
+  from resource_management.libraries.functions import get_kinit_path
+  from resource_management.libraries.functions.get_not_managed_resources import get_not_managed_resources
+
+  klist_path_local = get_klist_path(default('/configurations/kerberos-env/executable_search_paths', None))
+  kinit_path_local = get_kinit_path(default('/configurations/kerberos-env/executable_search_paths', None))
+
+  # hadoop default parameters
+  hdfs_user = params.config['configurations']['hadoop-env']['hdfs_user']
+  hadoop_bin = stack_select.get_hadoop_dir("sbin")
+  hadoop_bin_dir = stack_select.get_hadoop_dir("bin")
+  hadoop_conf_dir = conf_select.get_hadoop_conf_dir()
+  hadoop_conf_secure_dir = os.path.join(hadoop_conf_dir, "secure")
+  hadoop_lib_home = stack_select.get_hadoop_dir("lib")
+  hdfs_principal_name = default('/configurations/hadoop-env/hdfs_principal_name', None)
+  hdfs_user_keytab = params.config['configurations']['hadoop-env']['hdfs_user_keytab']
+
+  dfs_type = default("/clusterLevelParams/dfs_type", "")
+
+  hdfs_site = params.config['configurations']['hdfs-site']
+  default_fs = params.config['configurations']['core-site']['fs.defaultFS']
+  #create partial functions with common arguments for every HdfsResource call
+  #to create/delete/copyfromlocal hdfs directories/files we need to call params.HdfsResource in code
+  HdfsResource = functools.partial(
+    HdfsResource,
+    user=params.infra_solr_user,
+    hdfs_resource_ignore_file = "/var/lib/ambari-agent/data/.hdfs_resource_ignore",
+    security_enabled = params.security_enabled,
+    keytab = keytab,
+    kinit_path_local = kinit_path_local,
+    hadoop_bin_dir = hadoop_bin_dir,
+    hadoop_conf_dir = hadoop_conf_dir,
+    principal_name = principal,
+    hdfs_site = hdfs_site,
+    default_fs = default_fs,
+    immutable_paths = get_not_managed_resources(),
+    dfs_type = dfs_type
+  )
+
+hostname_suffix = params.hostname.replace(".", "_")
+
+if shared_fs:
+  index_location = format("{index_location}_{hostname_suffix}")
+
+def get_files_by_pattern(directory, pattern):
+  for root, dirs, files in os.walk(directory):
+    for basename in files:
+      try:
+        matched = pattern.match(basename)
+      except AttributeError:
+        matched = fnmatch.fnmatch(basename, pattern)
+      if matched:
+        yield os.path.join(root, basename)
+
+def create_solr_api_request_command(request_path, output=None, override_solr_base_url=None):
+  solr_url = format("{solr_base_url}/{request_path}") if override_solr_base_url is None else format("{override_solr_base_url}/{request_path}")
+  grep_cmd = " | grep 'solr_rs_status: 200'"
+  api_cmd = format("kinit -kt {keytab} {principal} && curl -w'solr_rs_status: %{{http_code}}' -k --negotiate -u : '{solr_url}'") \
+    if params.security_enabled else format("curl -w'solr_rs_status: %{{http_code}}' -k '{solr_url}'")
+  if output is not None:
+    api_cmd+=format(" -o {output}")
+  api_cmd+=grep_cmd
+  return api_cmd
+
+def snapshot_status_check(request_cmd, json_output, snapshot_name, backup=True, log_output=True, tries=30, time_interval=5):
+  """
+  Check BACKUP/RESTORE status until the response status will be successful or failed.
+
+  :param request_cmd: backup or restore api path
+  :param json_output: json file which will store the response output
+  :param snapshot_name: snapshot name, it will be used to check the proper status in the status response (backup: <snapshot_name>, restore: snapshot.<snapshot_name>)
+  :param backup: this flag is true if the check is against backup, otherwise it will be restore
+  :param log_output: print the output of the downloaded json file (backup/restore response)
+  :param tries: number of tries of the requests - it stops after the response status is successful for backup/restore
+  :param time_interval: time to wait in seconds between retries
+  """
+  failed = True
+  num_tries = 0
+  for i in range(tries):
+    try:
+      num_tries+=1
+      if (num_tries > 1):
+        Logger.info(format("Number of tries: {num_tries} ..."))
+      Execute(request_cmd, user=params.infra_solr_user)
+      with open(json_output) as json_file:
+        json_data = json.load(json_file)
+        if backup:
+          details = json_data['details']
+          if 'backup' in details:
+            backup_list = details['backup']
+            if log_output:
+              Logger.info(str(backup_list))
+
+            if type(backup_list) == type(list()): # support map and list format as well
+              backup_data = dict(backup_list[i:i+2] for i in range(0, len(backup_list), 2))
+            else:
+              backup_data = backup_list
+
+            if (not 'snapshotName' in backup_data) or backup_data['snapshotName'] != snapshot_name:
+              snapshot = backup_data['snapshotName']
+              Logger.info(format("Snapshot name: {snapshot}, wait until {snapshot_name} will be available."))
+              time.sleep(time_interval)
+              continue
+
+            if backup_data['status'] == 'success':
+              Logger.info("Backup command status: success.")
+              failed = False
+            elif backup_data['status'] == 'failed':
+              Logger.info("Backup command status: failed.")
+            else:
+              Logger.info(format("Backup command is in progress... Sleep for {time_interval} seconds."))
+              time.sleep(time_interval)
+              continue
+          else:
+            Logger.info("Backup data is not found yet in details JSON response...")
+            time.sleep(time_interval)
+            continue
+
+        else:
+          if 'restorestatus' in json_data:
+            restorestatus_data = json_data['restorestatus']
+            if log_output:
+              Logger.info(str(restorestatus_data))
+
+            if (not 'snapshotName' in restorestatus_data) or restorestatus_data['snapshotName'] != format("snapshot.{snapshot_name}"):
+              snapshot = restorestatus_data['snapshotName']
+              Logger.info(format("Snapshot name: {snapshot}, wait until snapshot.{snapshot_name} will be available."))
+              time.sleep(time_interval)
+              continue
+
+            if restorestatus_data['status'] == 'success':
+              Logger.info("Restore command successfully finished.")
+              failed = False
+            elif restorestatus_data['status'] == 'failed':
+              Logger.info("Restore command failed.")
+            else:
+              Logger.info(format("Restore command is in progress... Sleep for {time_interval} seconds."))
+              time.sleep(time_interval)
+              continue
+          else:
+            Logger.info("Restore status data is not found yet in details JSON response...")
+            time.sleep(time_interval)
+            continue
+
+
+    except Exception:
+      traceback.print_exc()
+      time.sleep(time_interval)
+      continue
+    break
+
+  if failed:
+    raise Exception("Status Command failed.")
+  else:
+    Logger.info("Status command finished successfully.")
+
+def __get_domain_name(url):
+  spltAr = url.split("://")
+  i = (0,1)[len(spltAr) > 1]
+  dm = spltAr[i].split('/')[0].split(':')[0].lower()
+  return dm
+
+def write_core_file(core, core_data):
+  core_json_location = format("{index_location}/{core}.json")
+  File(core_json_location, content=json.dumps(core_data))
+
+def create_core_pairs(original_cores, new_cores):
+  """
+  Create core pairss from the original and new cores (backups -> restored ones), use alphabetic order
+  """
+  core_pairs_data=[]
+  if len(new_cores) < len(original_cores):
+    raise Exception("Old collection core size is: " + str(len(new_cores)) +
+                    ". You will need at least: " + str(len(original_cores)))
+  else:
+    for index, core_data in enumerate(original_cores):
+      value={}
+      value['src_core']=core_data[0]
+      value['src_host']=core_data[1]
+      value['target_core']=new_cores[index][0]
+      value['target_host']=new_cores[index][1]
+      core_pairs_data.append(value)
+    File(format("{index_location}/restore_core_pairs.json"), content=json.dumps(core_pairs_data))
+    return core_pairs_data
+
+def sort_core_host_pairs(host_core_map):
+  """
+  Sort host core map by key
+  """
+  core_host_pairs=[]
+  for key in sorted(host_core_map):
+    core_host_pairs.append((key, host_core_map[key]))
+  return core_host_pairs
+
+def is_ip(addr):
+  try:
+    socket.inet_aton(addr)
+    return True
+  except socket.error:
+    return False
+
+def resolve_ip_to_hostname(ip):
+  try:
+    host_name = socket.gethostbyaddr(ip)[0].lower()
+    Logger.info(format("Resolved {ip} to {host_name}"))
+    fqdn_name = socket.getaddrinfo(host_name, 0, 0, 0, 0, socket.AI_CANONNAME)[0][3].lower()
+    return host_name if host_name == fqdn_name else fqdn_name
+  except socket.error:
+    pass
+  return ip
+
+def create_command(command):
+  """
+  Create hdfs command. Append kinit to the command if required.
+  """
+  kinit_cmd = "{0} -kt {1} {2};".format(kinit_path_local, params.infra_solr_kerberos_keytab, params.infra_solr_kerberos_principal) if params.security_enabled else ""
+  return kinit_cmd + command
+
+def execute_commad(command):
+  """
+  Run hdfs command by infra-solr user
+  """
+  return call(command, user=params.infra_solr_user, timeout=300)
+
+def move_hdfs_folder(source_dir, target_dir):
+  cmd=create_command(format('hdfs dfs -mv {source_dir} {target_dir}'))
+  returncode, stdout = execute_commad(cmd)
+  if returncode:
+    raise Exception("Unable to move HDFS dir '{0}' to '{1}' (return code: {2})".format(source_dir, target_dir, str(returncode)))
+  return stdout.strip()
+
+def check_hdfs_folder_exists(hdfs_dir):
+  """
+  Check that hdfs folder exists or not
+  """
+  cmd=create_command(format("hdfs dfs -ls {hdfs_dir}"))
+  returncode, stdout = execute_commad(cmd)
+  if returncode:
+    return False
+  return True
+
+def check_folder_exists(dir):
+  """
+  Check that folder exists or not
+  """
+  returncode, stdout = call(format("test -d {dir}"), user=params.infra_solr_user, timeout=300)
+  if returncode:
+    return False
+  return True
+
+def check_folder_until_size_not_changes(dir):
+  """
+  Call du -d 0 <folder> | cut -f 1 on specific directory until the size not changes (so copy operation has finished)
+  """
+  cmd = format("du -d 0 {dir} | cut -f 1")
+  size_changed = True
+  size_str = "-1"
+  while size_changed:
+    returncode, stdout = call(cmd, user=params.infra_solr_user, timeout=300)
+    if stdout:
+      actual_size_str = stdout.strip()
+      if actual_size_str == size_str:
+        size_changed = False
+        continue
+      else:
+        Logger.info(format("Actual size of '{dir}' is {actual_size_str}, wait 5 sec and check again, to make sure no copy operation is in progress..."))
+        time.sleep(5)
+        size_str = actual_size_str

BIN
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/command_commons.pyo


+ 171 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/infra_solr.py

@@ -0,0 +1,171 @@
+"""
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+"""
+
+import sys
+from ambari_commons.repo_manager import ManagerFactory
+from ambari_commons.shell import RepoCallContext
+from resource_management.core.logger import Logger
+from resource_management.core.source import Template
+from resource_management.core.resources.system import Execute, File
+from resource_management.core.resources.zkmigrator import ZkMigrator
+from resource_management.libraries.functions.check_process_status import check_process_status
+from resource_management.libraries.functions.default import default
+from resource_management.libraries.functions.format import format
+from resource_management.libraries.functions.get_user_call_output import get_user_call_output
+from resource_management.libraries.functions.show_logs import show_logs
+from resource_management.libraries.script.script import Script
+from resource_management.libraries.functions.generate_logfeeder_input_config import generate_logfeeder_input_config
+
+from collection import backup_collection, restore_collection
+from migrate import migrate_index
+from setup_infra_solr import setup_infra_solr, setup_solr_znode_env
+
+class InfraSolr(Script):
+  def install(self, env):
+    import params
+    env.set_params(params)
+    self.install_packages(env)
+
+  def configure(self, env, upgrade_type=None):
+    import params
+    env.set_params(params)
+
+    setup_infra_solr(name = 'server')
+
+  def start(self, env, upgrade_type=None):
+    import params
+    env.set_params(params)
+    self.configure(env)
+
+    generate_logfeeder_input_config('ambari-infra', Template("input.config-ambari-infra.json.j2", extra_imports=[default]))
+
+    setup_solr_znode_env()
+    start_cmd = format('{solr_bindir}/solr start -cloud -noprompt -s {infra_solr_datadir} -Dsolr.kerberos.name.rules=\'{infra_solr_kerberos_name_rules}\' 2>&1') \
+            if params.security_enabled else format('{solr_bindir}/solr start -cloud -noprompt -s {infra_solr_datadir} 2>&1')
+
+    check_process = format("{sudo} test -f {infra_solr_pidfile} && {sudo} pgrep -F {infra_solr_pidfile}")
+
+    piped_start_cmd = format('{start_cmd} | tee {infra_solr_log}') + '; (exit "${PIPESTATUS[0]}")'
+    Execute(
+      piped_start_cmd,
+      environment={'SOLR_INCLUDE': format('{infra_solr_conf}/infra-solr-env.sh')},
+      user=params.infra_solr_user,
+      not_if=check_process,
+      logoutput=True
+    )
+
+  def stop(self, env, upgrade_type=None):
+    import params
+    env.set_params(params)
+
+    try:
+      stop_cmd=format('{solr_bindir}/solr stop -all')
+      piped_stop_cmd=format('{stop_cmd} | tee {infra_solr_log}') + '; (exit "${PIPESTATUS[0]}")'
+      Execute(piped_stop_cmd,
+              environment={'SOLR_INCLUDE': format('{infra_solr_conf}/infra-solr-env.sh')},
+              user=params.infra_solr_user,
+              logoutput=True
+              )
+
+      File(params.prev_infra_solr_pidfile,
+           action="delete"
+           )
+    except:
+      Logger.warning("Could not stop solr:" + str(sys.exc_info()[1]) + "\n Trying to kill it")
+      self.kill_process(params.prev_infra_solr_pidfile, params.infra_solr_user, params.infra_solr_log_dir)
+
+  def status(self, env):
+    import status_params
+    env.set_params(status_params)
+
+    check_process_status(status_params.infra_solr_pidfile)
+
+  def kill_process(self, pid_file, user, log_dir):
+    """
+    Kill the process by pid file, then check the process is running or not. If the process is still running after the kill
+    command, it will try to kill with -9 option (hard kill)
+    """
+    pid = get_user_call_output(format("cat {pid_file}"), user=user, is_checked_call=False)[1]
+    process_id_exists_command = format("ls {pid_file} >/dev/null 2>&1 && ps -p {pid} >/dev/null 2>&1")
+
+    kill_cmd = format("{sudo} kill {pid}")
+    Execute(kill_cmd,
+          not_if=format("! ({process_id_exists_command})"))
+    wait_time = 5
+
+    hard_kill_cmd = format("{sudo} kill -9 {pid}")
+    Execute(hard_kill_cmd,
+          not_if=format("! ({process_id_exists_command}) || ( sleep {wait_time} && ! ({process_id_exists_command}) )"),
+          ignore_failures=True)
+    try:
+      Execute(format("! ({process_id_exists_command})"),
+            tries=20,
+            try_sleep=3,
+            )
+    except:
+      show_logs(log_dir, user)
+      raise
+
+    File(pid_file,
+       action="delete"
+       )
+
+  def disable_security(self, env):
+    import params
+    if not params.infra_solr_znode:
+      Logger.info("Skipping reverting ACL")
+      return
+    zkmigrator = ZkMigrator(
+      zk_host=params.zk_quorum,
+      java_exec=params.java_exec,
+      java_home=params.java64_home,
+      jaas_file=params.infra_solr_jaas_file,
+      user=params.infra_solr_user)
+    zkmigrator.set_acls(params.infra_solr_znode, 'world:anyone:crdwa')
+
+  def backup(self, env):
+    backup_collection(env)
+
+  def restore(self, env):
+    restore_collection(env)
+
+  def migrate(self, env):
+    migrate_index(env)
+
+  def upgrade_solr_instance(self, env):
+    pkg_provider = ManagerFactory.get()
+    context = RepoCallContext()
+    context.log_output = True
+    pkg_provider.remove_package('ambari-infra-solr', context, ignore_dependencies=True)
+    pkg_provider.upgrade_package('ambari-infra-solr', context)
+
+  def get_log_folder(self):
+    import params
+    return params.infra_solr_log_dir
+
+  def get_user(self):
+    import params
+    return params.infra_solr_user
+
+  def get_pid_files(self):
+    import status_params
+    return [status_params.infra_solr_pidfile]
+
+if __name__ == "__main__":
+  InfraSolr().execute()

BIN
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/infra_solr.pyo


+ 60 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/infra_solr_client.py

@@ -0,0 +1,60 @@
+"""
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+"""
+
+from ambari_commons.repo_manager import ManagerFactory
+from ambari_commons.shell import RepoCallContext
+from resource_management.core.exceptions import ClientComponentHasNoStatus
+from resource_management.libraries.script.script import Script
+
+from setup_infra_solr import setup_infra_solr
+
+class InfraSolrClient(Script):
+
+  def install(self, env):
+    import params
+    env.set_params(params)
+    self.install_packages(env)
+    self.configure(env)
+
+  def configure(self, env, upgrade_type=None):
+    import params
+    env.set_params(params)
+    setup_infra_solr(name ='client')
+
+  def start(self, env, upgrade_type=None):
+    import params
+    env.set_params(params)
+    self.configure(env)
+
+  def stop(self, env, upgrade_type=None):
+    import params
+    env.set_params(params)
+
+  def status(self, env):
+    raise ClientComponentHasNoStatus()
+
+  def upgrade_solr_client(self, env):
+    pkg_provider = ManagerFactory.get()
+    context = RepoCallContext()
+    context.log_output = True
+    pkg_provider.remove_package('ambari-infra-solr-client', context, ignore_dependencies=True)
+    pkg_provider.upgrade_package('ambari-infra-solr-client', context)
+
+if __name__ == "__main__":
+  InfraSolrClient().execute()

BIN
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/infra_solr_client.pyo


+ 62 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/migrate.py

@@ -0,0 +1,62 @@
+"""
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+"""
+
+from resource_management.core.logger import Logger
+from resource_management.core.resources.system import Execute, File
+from resource_management.libraries.functions.format import format
+
+def migrate_index(env):
+  """
+  Migrate lucene index in the background.
+  """
+  import params, command_commons
+  env.set_params(command_commons)
+
+  index_migrate_cmd = format("{index_helper_script} upgrade-index -d {index_location} -v {index_version}")
+
+  if command_commons.force is True:
+    index_migrate_cmd+=" -f"
+
+  if command_commons.backup_mode is True:
+    index_migrate_cmd+=" -b"
+
+  if command_commons.debug is True:
+    index_migrate_cmd+=" -g"
+
+  if command_commons.core_filter is not None:
+    index_migrate_cmd+=format(" -c {core_filter}")
+
+  deleted_write_locks=[]
+  if command_commons.delete_lock_on_start:
+    Logger.info(format("Remove write.lock files from folder '{index_location}'"))
+    for write_lock_file in command_commons.get_files_by_pattern(format("{index_location}"), 'write.lock'):
+      File(write_lock_file, action="delete")
+      deleted_write_locks.append(write_lock_file)
+  else:
+    Logger.info("Skip removing write.lock files")
+
+  Logger.info(format("Migrate index at location: {index_location}"))
+  # It can generate a write.lock file
+  Execute(index_migrate_cmd, user=params.infra_solr_user, environment={'JAVA_HOME': params.java64_home}, logoutput=command_commons.log_output)
+
+  if command_commons.delete_lock_on_start:
+    for write_lock_file in deleted_write_locks:
+      Logger.info(format("Put '{write_lock_file}' file back"))
+      File(write_lock_file, action="create", mode = 0644, owner=params.infra_solr_user, group=params.user_group, not_if=format("test -f {write_lock_file}"))
+

BIN
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/migrate.pyo


+ 219 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/params.py

@@ -0,0 +1,219 @@
+"""
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+"""
+
+import os
+from ambari_commons.constants import AMBARI_SUDO_BINARY
+from resource_management.libraries.functions.default import default
+from resource_management.libraries.functions.format import format
+from resource_management.libraries.functions.is_empty import is_empty
+from resource_management.libraries.script.script import Script
+
+import status_params
+
+
+def get_port_from_url(address):
+  if not is_empty(address):
+    return address.split(':')[-1]
+  else:
+    return address
+
+def get_name_from_principal(principal):
+  if not principal:  # return if empty
+    return principal
+  slash_split = principal.split('/')
+  if len(slash_split) == 2:
+    return slash_split[0]
+  else:
+    at_split = principal.split('@')
+    return at_split[0]
+
+# config object that holds the configurations declared in the -site.xml file
+config = Script.get_config()
+tmp_dir = Script.get_tmp_dir()
+
+stack_version = default("/commandParams/version", None)
+sudo = AMBARI_SUDO_BINARY
+security_enabled = status_params.security_enabled
+
+hostname = config['agentLevelParams']['hostname'].lower()
+
+infra_solr_conf = "/etc/ambari-infra-solr/conf"
+
+infra_solr_port = status_params.infra_solr_port
+infra_solr_piddir = status_params.infra_solr_piddir
+infra_solr_pidfile = status_params.infra_solr_pidfile
+prev_infra_solr_pidfile = status_params.prev_infra_solr_pidfile
+
+user_group = config['configurations']['cluster-env']['user_group']
+fetch_nonlocal_groups = config['configurations']['cluster-env']["fetch_nonlocal_groups"]
+
+limits_conf_dir = "/etc/security/limits.d"
+infra_solr_user_nofile_limit = default("/configurations/infra-solr-env/infra_solr_user_nofile_limit", "128000")
+infra_solr_user_nproc_limit = default("/configurations/infra-solr-env/infra_solr_user_nproc_limit", "65536")
+
+# shared configs
+java_home = config['ambariLevelParams']['java_home']
+ambari_java_home = default("/ambariLevelParams/ambari_java_home", None)
+java64_home = ambari_java_home if ambari_java_home is not None else java_home
+java_exec = format("{java64_home}/bin/java")
+zookeeper_hosts_list = config['clusterHostInfo']['zookeeper_server_hosts']
+zookeeper_hosts_list.sort()
+# get comma separated list of zookeeper hosts from clusterHostInfo
+zookeeper_hosts = ",".join(zookeeper_hosts_list)
+
+#####################################
+# Solr configs
+#####################################
+
+# Only supporting SolrCloud mode - so hardcode those options
+solr_cloudmode = 'true'
+solr_dir = '/usr/lib/ambari-infra-solr'
+solr_client_dir = '/usr/lib/ambari-infra-solr-client'
+solr_bindir = solr_dir + '/bin'
+cloud_scripts = solr_dir + '/server/scripts/cloud-scripts'
+
+logsearch_hosts = default("/clusterHostInfo/logsearch_server_hosts", [])
+has_logsearch = len(logsearch_hosts) > 0
+
+zookeeper_port = default('/configurations/zoo.cfg/clientPort', None)
+# get comma separated list of zookeeper hosts from clusterHostInfo
+index = 0
+zookeeper_quorum = ""
+for host in config['clusterHostInfo']['zookeeper_server_hosts']:
+  zookeeper_quorum += host + ":" + str(zookeeper_port)
+  index += 1
+  if index < len(config['clusterHostInfo']['zookeeper_server_hosts']):
+    zookeeper_quorum += ","
+
+if "infra-solr-env" in config['configurations']:
+  infra_solr_hosts = config['clusterHostInfo']['infra_solr_hosts']
+  infra_solr_znode = config['configurations']['infra-solr-env']['infra_solr_znode']
+  infra_solr_min_mem = format(config['configurations']['infra-solr-env']['infra_solr_minmem'])
+  infra_solr_max_mem = format(config['configurations']['infra-solr-env']['infra_solr_maxmem'])
+  infra_solr_java_stack_size = format(config['configurations']['infra-solr-env']['infra_solr_java_stack_size'])
+  infra_solr_instance_count = len(config['clusterHostInfo']['infra_solr_hosts'])
+  infra_solr_datadir = format(config['configurations']['infra-solr-env']['infra_solr_datadir'])
+  infra_solr_data_resources_dir = os.path.join(infra_solr_datadir, 'resources')
+  infra_solr_jmx_port = config['configurations']['infra-solr-env']['infra_solr_jmx_port']
+  infra_solr_ssl_enabled = default('configurations/infra-solr-env/infra_solr_ssl_enabled', False)
+  infra_solr_keystore_location = config['configurations']['infra-solr-env']['infra_solr_keystore_location']
+  infra_solr_keystore_password = config['configurations']['infra-solr-env']['infra_solr_keystore_password']
+  infra_solr_keystore_type = config['configurations']['infra-solr-env']['infra_solr_keystore_type']
+  infra_solr_truststore_location = config['configurations']['infra-solr-env']['infra_solr_truststore_location']
+  infra_solr_truststore_password = config['configurations']['infra-solr-env']['infra_solr_truststore_password']
+  infra_solr_truststore_type = config['configurations']['infra-solr-env']['infra_solr_truststore_type']
+  infra_solr_user = config['configurations']['infra-solr-env']['infra_solr_user']
+  infra_solr_log_dir = config['configurations']['infra-solr-env']['infra_solr_log_dir']
+  infra_solr_log = format("{infra_solr_log_dir}/solr-install.log")
+  solr_env_content = config['configurations']['infra-solr-env']['content']
+  infra_solr_gc_log_opts = format(config['configurations']['infra-solr-env']['infra_solr_gc_log_opts'])
+  infra_solr_gc_tune = format(config['configurations']['infra-solr-env']['infra_solr_gc_tune'])
+  infra_solr_extra_java_opts = format(default('configurations/infra-solr-env/infra_solr_extra_java_opts', ""))
+
+  zk_quorum = format(default('configurations/infra-solr-env/infra_solr_zookeeper_quorum', zookeeper_quorum))
+
+if 'infra-solr-security-json' in config['configurations']:
+  infra_solr_security_manually_managed = default("/configurations/infra-solr-security-json/infra_solr_security_manually_managed", False)
+
+default_ranger_audit_users = 'nn,hbase,hive,knox,kafka,kms,storm,yarn,nifi'
+
+if security_enabled:
+  kinit_path_local = status_params.kinit_path_local
+  _hostname_lowercase = config['agentLevelParams']['hostname'].lower()
+  infra_solr_jaas_file = infra_solr_conf + '/infra_solr_jaas.conf'
+  infra_solr_kerberos_keytab = config['configurations']['infra-solr-env']['infra_solr_kerberos_keytab']
+  infra_solr_kerberos_principal = config['configurations']['infra-solr-env']['infra_solr_kerberos_principal'].replace('_HOST',_hostname_lowercase)
+  infra_solr_web_kerberos_keytab = config['configurations']['infra-solr-env']['infra_solr_web_kerberos_keytab']
+  infra_solr_web_kerberos_principal = config['configurations']['infra-solr-env']['infra_solr_web_kerberos_principal'].replace('_HOST',_hostname_lowercase)
+  infra_solr_kerberos_name_rules = config['configurations']['infra-solr-env']['infra_solr_kerberos_name_rules']
+  infra_solr_sasl_user = get_name_from_principal(infra_solr_kerberos_principal)
+  kerberos_realm = config['configurations']['kerberos-env']['realm']
+
+  zookeeper_principal_name = default("/configurations/zookeeper-env/zookeeper_principal_name", "zookeeper/_HOST@EXAMPLE.COM")
+  external_zk_principal_enabled = default("/configurations/infra-solr-env/infra_solr_zookeeper_external_enabled", False)
+  external_zk_principal_name = default("/configurations/infra-solr-env/infra_solr_zookeeper_external_principal", "zookeeper/_HOST@EXAMPLE.COM")
+  zk_principal_name = external_zk_principal_name if external_zk_principal_enabled else zookeeper_principal_name
+  zk_principal_user = zk_principal_name.split('/')[0]
+  zk_security_opts = format('-Dzookeeper.sasl.client=true -Dzookeeper.sasl.client.username={zk_principal_user} -Dzookeeper.sasl.clientconfig=Client')
+
+  ranger_audit_principal_conf_key = "xasecure.audit.jaas.Client.option.principal"
+  ranger_audit_principals = []
+  ranger_audit_principals.append(default('configurations/ranger-hdfs-audit/' + ranger_audit_principal_conf_key, 'nn'))
+  ranger_audit_principals.append(default('configurations/ranger-hbase-audit/' + ranger_audit_principal_conf_key, 'hbase'))
+  ranger_audit_principals.append(default('configurations/ranger-hive-audit/' + ranger_audit_principal_conf_key, 'hive'))
+  ranger_audit_principals.append(default('configurations/ranger-knox-audit/' + ranger_audit_principal_conf_key, 'knox'))
+  ranger_audit_principals.append(default('configurations/ranger-kafka-audit/' + ranger_audit_principal_conf_key, 'kafka'))
+  ranger_audit_principals.append(default('configurations/ranger-kms-audit/' + ranger_audit_principal_conf_key, 'rangerkms'))
+  ranger_audit_principals.append(default('configurations/ranger-storm-audit/' + ranger_audit_principal_conf_key, 'storm'))
+  ranger_audit_principals.append(default('configurations/ranger-yarn-audit/' + ranger_audit_principal_conf_key, 'yarn'))
+  ranger_audit_principals.append(default('configurations/ranger-nifi-audit/' + ranger_audit_principal_conf_key, 'nifi'))
+  ranger_audit_names_from_principals = [ get_name_from_principal(x) for x in ranger_audit_principals ]
+  default_ranger_audit_users = ','.join(ranger_audit_names_from_principals)
+
+  infra_solr_logsearch_service_users = []
+  logsearch_kerberos_service_user = get_name_from_principal(default('/configurations/logsearch-env/logsearch_kerberos_principal', 'logsearch'))
+  infra_solr_logsearch_service_users.append(logsearch_kerberos_service_user)
+  logsearch_kerberos_service_users_str = str(default('/configurations/logsearch-env/logsearch_kerberos_service_users', ''))
+  if logsearch_kerberos_service_users_str and logsearch_kerberos_service_users_str.strip():
+    logsearch_kerberos_service_users = logsearch_kerberos_service_users_str.split(',')
+    infra_solr_logsearch_service_users.extend(logsearch_kerberos_service_users)
+
+infra_solr_ranger_audit_service_users = format(config['configurations']['infra-solr-security-json']['infra_solr_ranger_audit_service_users']).split(',')
+infra_solr_security_json_content = config['configurations']['infra-solr-security-json']['content']
+
+infra_solr_jmx_enabled = str(default('/configurations/infra-solr-env/infra_solr_jmx_enabled', False)).lower()
+
+#Solr log4j
+infra_log_maxfilesize = default('configurations/infra-solr-log4j/infra_log_maxfilesize',10)
+infra_log_maxbackupindex = default('configurations/infra-solr-log4j/infra_log_maxbackupindex',9)
+
+solr_xml_content = default('configurations/infra-solr-xml/content', None)
+solr_log4j_content = default('configurations/infra-solr-log4j/content', None)
+
+smokeuser = config['configurations']['cluster-env']['smokeuser']
+smoke_user_keytab = config['configurations']['cluster-env']['smokeuser_keytab']
+smokeuser_principal = config['configurations']['cluster-env']['smokeuser_principal_name']
+
+ranger_solr_collection_name = default('configurations/ranger-env/ranger_solr_collection_name', 'ranger_audits')
+logsearch_service_logs_collection = default('configurations/logsearch-properties/logsearch.solr.collection.service.logs', 'hadoop_logs')
+logsearch_audit_logs_collection = default('configurations/logsearch-properties/logsearch.solr.collection.audit.logs', 'audit_logs')
+
+ranger_admin_kerberos_service_user = get_name_from_principal(default('configurations/ranger-admin-site/ranger.admin.kerberos.principal', 'rangeradmin'))
+atlas_kerberos_service_user = get_name_from_principal(default('configurations/application-properties/atlas.authentication.principal', 'atlas'))
+logfeeder_kerberos_service_user = get_name_from_principal(default('configurations/logfeeder-env/logfeeder_kerberos_principal', 'logfeeder'))
+infra_solr_kerberos_service_user = get_name_from_principal(default('configurations/infra-solr-env/infra_solr_kerberos_principal', 'infra-solr'))
+
+infra_solr_role_ranger_admin = default('configurations/infra-solr-security-json/infra_solr_role_ranger_admin', 'ranger_user')
+infra_solr_role_ranger_audit = default('configurations/infra-solr-security-json/infra_solr_role_ranger_audit', 'ranger_audit_user')
+infra_solr_role_atlas = default('configurations/infra-solr-security-json/infra_solr_role_atlas', 'atlas_user')
+infra_solr_role_logsearch = default('configurations/infra-solr-security-json/infra_solr_role_logsearch', 'logsearch_user')
+infra_solr_role_logfeeder = default('configurations/infra-solr-security-json/infra_solr_role_logfeeder', 'logfeeder_user')
+infra_solr_role_dev = default('configurations/infra-solr-security-json/infra_solr_role_dev', 'dev')
+
+ams_collector_hosts = ",".join(default("/clusterHostInfo/metrics_collector_hosts", []))
+metrics_enabled = ams_collector_hosts != ''
+if metrics_enabled:
+  metrics_http_policy = config['configurations']['ams-site']['timeline.metrics.service.http.policy']
+  ams_collector_protocol = 'http'
+  if metrics_http_policy == 'HTTPS_ONLY':
+    ams_collector_protocol = 'https'
+  ams_collector_port = str(get_port_from_url(config['configurations']['ams-site']['timeline.metrics.service.webapp.address']))
+else:
+  ams_collector_port = ''
+  ams_collector_protocol = ''

BIN
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/params.pyo


+ 48 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/service_check.py

@@ -0,0 +1,48 @@
+"""
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+"""
+
+from resource_management.core.logger import Logger
+from resource_management.core.resources.system import Execute
+from resource_management.libraries.functions.format import format
+from resource_management.libraries.script.script import Script
+
+class InfraServiceCheck(Script):
+  def service_check(self, env):
+    import params
+    env.set_params(params)
+
+    Logger.info('Infra Service Check ...')
+    if "infra-solr-env" in params.config['configurations'] \
+      and params.infra_solr_hosts is not None \
+      and len(params.infra_solr_hosts) > 0:
+      solr_protocol = "https" if params.infra_solr_ssl_enabled else "http"
+      solr_host = params.infra_solr_hosts[0] # choose the first solr host
+      solr_port = params.infra_solr_port
+      solr_url = format("{solr_protocol}://{solr_host}:{solr_port}/solr/#/")
+
+      smokeuser_kinit_cmd = format("{kinit_path_local} -kt {smoke_user_keytab} {smokeuser_principal};") if params.security_enabled else ""
+      smoke_infra_solr_cmd = format("{smokeuser_kinit_cmd} curl -s -o /dev/null -w'%{{http_code}}' --negotiate -u: -k {solr_url} | grep 200")
+      Execute(smoke_infra_solr_cmd,
+              tries = 40,
+              try_sleep=3,
+              user=params.smokeuser,
+              logoutput=True)
+
+if __name__ == "__main__":
+  InfraServiceCheck().execute()

BIN
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/service_check.pyo


+ 163 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/setup_infra_solr.py

@@ -0,0 +1,163 @@
+"""
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+"""
+
+import os
+from resource_management.core.exceptions import Fail
+from resource_management.core.resources.system import Directory, File
+from resource_management.core.source import InlineTemplate, Template
+from resource_management.libraries.functions import solr_cloud_util
+from resource_management.libraries.functions.decorator import retry
+from resource_management.libraries.functions.format import format
+
+def setup_infra_solr(name = None):
+  import params
+
+  if name == 'server':
+    Directory([params.infra_solr_log_dir, params.infra_solr_piddir,
+               params.infra_solr_datadir, params.infra_solr_data_resources_dir],
+              mode=0755,
+              cd_access='a',
+              create_parents=True,
+              owner=params.infra_solr_user,
+              group=params.user_group
+              )
+
+    Directory([params.solr_dir, params.infra_solr_conf],
+              mode=0755,
+              cd_access='a',
+              owner=params.infra_solr_user,
+              group=params.user_group,
+              create_parents=True,
+              recursive_ownership=True
+              )
+
+    File(params.infra_solr_log,
+         mode=0644,
+         owner=params.infra_solr_user,
+         group=params.user_group,
+         content=''
+         )
+
+    File(format("{infra_solr_conf}/infra-solr-env.sh"),
+         content=InlineTemplate(params.solr_env_content),
+         mode=0755,
+         owner=params.infra_solr_user,
+         group=params.user_group
+         )
+
+    File(format("{infra_solr_datadir}/solr.xml"),
+         content=InlineTemplate(params.solr_xml_content),
+         owner=params.infra_solr_user,
+         group=params.user_group
+         )
+
+    File(format("{infra_solr_conf}/log4j2.xml"),
+         content=InlineTemplate(params.solr_log4j_content),
+         owner=params.infra_solr_user,
+         group=params.user_group
+         )
+
+    custom_security_json_location = format("{infra_solr_conf}/custom-security.json")
+    File(custom_security_json_location,
+         content=InlineTemplate(params.infra_solr_security_json_content),
+         owner=params.infra_solr_user,
+         group=params.user_group,
+         mode=0640
+         )
+
+    if params.security_enabled:
+      File(format("{infra_solr_jaas_file}"),
+           content=Template("infra_solr_jaas.conf.j2"),
+           owner=params.infra_solr_user)
+
+      File(format("{infra_solr_conf}/security.json"),
+           content=Template("infra-solr-security.json.j2"),
+           owner=params.infra_solr_user,
+           group=params.user_group,
+           mode=0640)
+    if os.path.exists(params.limits_conf_dir):
+      File(os.path.join(params.limits_conf_dir, 'infra-solr.conf'),
+           owner='root',
+           group='root',
+           mode=0644,
+           content=Template("infra-solr.conf.j2")
+      )
+
+  elif name == 'client':
+    solr_cloud_util.setup_solr_client(params.config)
+
+  else :
+    raise Fail('Nor client or server were selected to install.')
+
+def setup_solr_znode_env():
+  """
+  Setup SSL, ACL and authentication / authorization related Zookeeper settings for Solr (checkout: /clustersprops.json and /security.json)
+  """
+  import params
+
+  custom_security_json_location = format("{infra_solr_conf}/custom-security.json")
+  jaas_file = params.infra_solr_jaas_file if params.security_enabled else None
+  java_opts = params.zk_security_opts if params.security_enabled else None
+  url_scheme = 'https' if params.infra_solr_ssl_enabled else 'http'
+
+  security_json_file_location = custom_security_json_location \
+    if params.infra_solr_security_json_content and str(params.infra_solr_security_json_content).strip() \
+    else format("{infra_solr_conf}/security.json") # security.json file to upload
+
+  create_ambari_solr_znode(java_opts, jaas_file)
+
+  solr_cloud_util.set_cluster_prop(
+    zookeeper_quorum=params.zk_quorum,
+    solr_znode=params.infra_solr_znode,
+    java64_home=params.java64_home,
+    prop_name="urlScheme",
+    prop_value=url_scheme,
+    jaas_file=jaas_file,
+    java_opts=java_opts
+  )
+  if not params.infra_solr_security_manually_managed:
+    solr_cloud_util.setup_kerberos_plugin(
+      zookeeper_quorum=params.zk_quorum,
+      solr_znode=params.infra_solr_znode,
+      jaas_file=jaas_file,
+      java64_home=params.java64_home,
+      secure=params.security_enabled,
+      security_json_location=security_json_file_location,
+      java_opts=java_opts
+    )
+
+  if params.security_enabled:
+    solr_cloud_util.secure_solr_znode(
+      zookeeper_quorum=params.zk_quorum,
+      solr_znode=params.infra_solr_znode,
+      jaas_file=jaas_file,
+      java64_home=params.java64_home,
+      sasl_users_str=params.infra_solr_sasl_user,
+      java_opts=java_opts
+    )
+
+
+@retry(times=30, sleep_time=5, err_class=Fail)
+def create_ambari_solr_znode(java_opts, jaas_file):
+  import params
+  solr_cloud_util.create_znode(
+    zookeeper_quorum=params.zk_quorum,
+    solr_znode=params.infra_solr_znode,
+    java64_home=params.java64_home,
+    retry=30, interval=5, java_opts=java_opts, jaas_file=jaas_file)

BIN
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/setup_infra_solr.pyo


+ 40 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/status_params.py

@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+"""
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+"""
+
+from os import listdir, path
+from resource_management.libraries.functions import get_kinit_path
+from resource_management.libraries.functions.default import default
+from resource_management.libraries.functions.format import format
+from resource_management.libraries.script.script import Script
+
+config = Script.get_config()
+
+infra_solr_port = default('configurations/infra-solr-env/infra_solr_port', '8886')
+infra_solr_piddir = default('configurations/infra-solr-env/infra_solr_pid_dir', '/var/run/ambari-infra-solr')
+infra_solr_pidfile = format("{infra_solr_piddir}/solr-{infra_solr_port}.pid")
+
+prev_infra_solr_pidfile = ''
+if path.isdir(infra_solr_piddir):
+  for file in listdir(infra_solr_piddir):
+    prev_infra_solr_pidfile = infra_solr_piddir + '/' + file
+
+security_enabled = config['configurations']['cluster-env']['security_enabled']
+kinit_path_local = get_kinit_path(default('/configurations/kerberos-env/executable_search_paths', None))

BIN
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/scripts/status_params.pyo


+ 84 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/templates/infra-solr-security.json.j2

@@ -0,0 +1,84 @@
+{#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#}
+{
+  "authentication": {
+    "class": "org.apache.solr.security.KerberosPlugin"
+  },
+  "authorization": {
+    "class": "org.apache.solr.security.InfraRuleBasedAuthorizationPlugin",
+    "user-role": {
+      "{{infra_solr_kerberos_service_user}}@{{kerberos_realm}}": "admin",
+{% if infra_solr_logsearch_service_users %}
+{%   for logsearch_kerberos_service_user in infra_solr_logsearch_service_users %}
+      "{{logsearch_kerberos_service_user}}@{{kerberos_realm}}": ["{{infra_solr_role_logsearch}}", "{{infra_solr_role_ranger_admin}}", "{{infra_solr_role_dev}}"],
+{%   endfor %}
+{% endif %}
+      "{{logfeeder_kerberos_service_user}}@{{kerberos_realm}}": ["{{infra_solr_role_logfeeder}}", "{{infra_solr_role_dev}}"],
+      "{{atlas_kerberos_service_user}}@{{kerberos_realm}}": ["{{infra_solr_role_atlas}}", "{{infra_solr_role_ranger_audit}}", "{{infra_solr_role_dev}}"],
+{% if infra_solr_ranger_audit_service_users %}
+{%   for ranger_audit_service_user in infra_solr_ranger_audit_service_users %}
+      "{{ranger_audit_service_user}}@{{kerberos_realm}}": ["{{infra_solr_role_ranger_audit}}", "{{infra_solr_role_dev}}"],
+{%   endfor %}
+{% endif %}
+      "{{ranger_admin_kerberos_service_user}}@{{kerberos_realm}}": ["{{infra_solr_role_ranger_admin}}", "{{infra_solr_role_ranger_audit}}", "{{infra_solr_role_dev}}"]
+    },
+    "permissions": [
+    {
+      "name" : "collection-admin-read",
+      "role" :null
+    },
+    {
+      "name" : "collection-admin-edit",
+      "role" : ["admin", "{{infra_solr_role_logsearch}}", "{{infra_solr_role_logfeeder}}", "{{infra_solr_role_atlas}}", "{{infra_solr_role_ranger_admin}}"]
+    },
+    {
+      "name":"read",
+      "role": "{{infra_solr_role_dev}}"
+    },
+    {
+      "collection": ["{{logsearch_service_logs_collection}}", "{{logsearch_audit_logs_collection}}", "history"],
+      "role": ["admin", "{{infra_solr_role_logsearch}}", "{{infra_solr_role_logfeeder}}"],
+      "name": "logsearch-manager",
+      "path": "/*"
+    },
+    {
+       "collection": ["vertex_index", "edge_index", "fulltext_index"],
+       "role": ["admin", "{{infra_solr_role_atlas}}"],
+       "name": "atlas-manager",
+       "path": "/*"
+    },
+    {
+       "collection": "{{ranger_solr_collection_name}}",
+       "role": ["admin", "{{infra_solr_role_ranger_admin}}", "{{infra_solr_role_ranger_audit}}"],
+       "name": "ranger-manager",
+       "path": "/*"
+    },
+    {
+       "collection": "old_ranger_audits",
+       "role": ["admin", "{{infra_solr_role_ranger_admin}}", "{{infra_solr_role_ranger_audit}}"],
+       "name": "backup-ranger-manager",
+       "path": "/*"
+    },
+    {
+       "collection": ["old_vertex_index", "old_edge_index", "old_fulltext_index"],
+       "role": ["admin", "{{infra_solr_role_atlas}}"],
+       "name": "backup-atlas-manager",
+       "path": "/*"
+    }]
+  }
+}

+ 17 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/templates/infra-solr.conf.j2

@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+{{infra_solr_user}}   - nofile {{infra_solr_user_nofile_limit}}
+{{infra_solr_user}}   - nproc  {{infra_solr_user_nproc_limit}}

+ 26 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/templates/infra_solr_jaas.conf.j2

@@ -0,0 +1,26 @@
+{#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#}
+
+Client {
+ com.sun.security.auth.module.Krb5LoginModule required
+ useKeyTab=true
+ storeKey=true
+ useTicketCache=false
+ keyTab="{{infra_solr_kerberos_keytab}}"
+ principal="{{infra_solr_kerberos_principal}}";
+};

+ 48 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/package/templates/input.config-ambari-infra.json.j2

@@ -0,0 +1,48 @@
+{#
+ # Licensed to the Apache Software Foundation (ASF) under one
+ # or more contributor license agreements.  See the NOTICE file
+ # distributed with this work for additional information
+ # regarding copyright ownership.  The ASF licenses this file
+ # to you under the Apache License, Version 2.0 (the
+ # "License"); you may not use this file except in compliance
+ # with the License.  You may obtain a copy of the License at
+ #
+ #   http://www.apache.org/licenses/LICENSE-2.0
+ #
+ # Unless required by applicable law or agreed to in writing, software
+ # distributed under the License is distributed on an "AS IS" BASIS,
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+ #}
+{
+  "input":[
+    {
+      "type":"infra_solr",
+      "rowtype":"service",
+      "path":"{{default('/configurations/infra-solr-env/infra_solr_log_dir', '/var/log/ambari-infra-solr')}}/solr.log"
+    }
+  ],
+  "filter":[
+    {
+      "filter":"grok",
+      "conditions":{
+        "fields":{
+          "type":[
+            "infra_solr"
+          ]
+        }
+      },
+      "log4j_format":"",
+      "multiline_pattern":"^(%{TIMESTAMP_ISO8601:logtime})",
+      "message_pattern":"(?m)^%{TIMESTAMP_ISO8601:logtime}%{SPACE}\\[%{DATA:thread_name}\\]%{SPACE}%{LOGLEVEL:level}%{SPACE}%{GREEDYDATA:log_message}",
+      "post_map_values":{
+        "logtime":{
+          "map_date":{
+            "target_date_pattern":"yyyy-MM-dd HH:mm:ss,SSS"
+          }
+        }
+      }
+    }
+  ]
+}

+ 108 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/properties/infra-solr-env.sh.j2

@@ -0,0 +1,108 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# By default the script will use JAVA_HOME to determine which java
+# to use, but you can set a specific path for Solr to use without
+# affecting other Java applications on your server/workstation.
+SOLR_JAVA_HOME={{java64_home}}
+
+# Increase Java Min/Max Heap as needed to support your indexing / query needs
+SOLR_JAVA_MEM="-Xms{{infra_solr_min_mem}}m -Xmx{{infra_solr_max_mem}}m"
+
+SOLR_JAVA_STACK_SIZE="-Xss{{infra_solr_java_stack_size}}m"
+
+GC_LOG_OPTS="{{infra_solr_gc_log_opts}} -Xloggc:{{infra_solr_log_dir}}/solr_gc.log"
+
+GC_TUNE="{{infra_solr_gc_tune}}"
+
+# Set the ZooKeeper connection string if using an external ZooKeeper ensemble
+# e.g. host1:2181,host2:2181/chroot
+# Leave empty if not using SolrCloud
+ZK_HOST="{{zookeeper_quorum}}{{infra_solr_znode}}"
+
+# Set the ZooKeeper client timeout (for SolrCloud mode)
+ZK_CLIENT_TIMEOUT="60000"
+
+# By default the start script uses "localhost"; override the hostname here
+# for production SolrCloud environments to control the hostname exposed to cluster state
+SOLR_HOST=`hostname -f`
+
+# By default the start script uses UTC; override the timezone if needed
+#SOLR_TIMEZONE="UTC"
+
+# Set to true to activate the JMX RMI connector to allow remote JMX client applications
+# to monitor the JVM hosting Solr; set to "false" to disable that behavior
+# (false is recommended in production environments)
+ENABLE_REMOTE_JMX_OPTS="{{infra_solr_jmx_enabled}}"
+
+# The script will use SOLR_PORT+10000 for the RMI_PORT or you can set it here
+RMI_PORT={{infra_solr_jmx_port}}
+
+# Anything you add to the SOLR_OPTS variable will be included in the java
+# start command line as-is, in ADDITION to other options. If you specify the
+# -a option on start script, those options will be appended as well. Examples:
+#SOLR_OPTS="$SOLR_OPTS -Dsolr.autoSoftCommit.maxTime=3000"
+#SOLR_OPTS="$SOLR_OPTS -Dsolr.autoCommit.maxTime=60000"
+#SOLR_OPTS="$SOLR_OPTS -Dsolr.clustering.enabled=true"
+SOLR_OPTS="$SOLR_OPTS -Djava.rmi.server.hostname={{hostname}}"
+{% if infra_solr_extra_java_opts -%}
+SOLR_OPTS="$SOLR_OPTS {{infra_solr_extra_java_opts}}"
+{% endif %}
+
+# Location where the bin/solr script will save PID files for running instances
+# If not set, the script will create PID files in $SOLR_TIP/bin
+SOLR_PID_DIR={{infra_solr_piddir}}
+
+# Path to a directory where Solr creates index files, the specified directory
+# must contain a solr.xml; by default, Solr will use server/solr
+SOLR_HOME={{infra_solr_datadir}}
+
+# Solr provides a default Log4J configuration properties file in server/resources
+# however, you may want to customize the log settings and file appender location
+# so you can point the script to use a different log4j.properties file
+LOG4J_PROPS={{infra_solr_conf}}/log4j2.xml
+
+# Location where Solr should write logs to; should agree with the file appender
+# settings in server/resources/log4j.properties
+SOLR_LOGS_DIR={{infra_solr_log_dir}}
+
+# Sets the port Solr binds to, default is 8983
+SOLR_PORT={{infra_solr_port}}
+
+# Be sure to update the paths to the correct keystore for your environment
+{% if infra_solr_ssl_enabled %}
+SOLR_SSL_KEY_STORE={{infra_solr_keystore_location}}
+SOLR_SSL_KEY_STORE_PASSWORD={{infra_solr_keystore_password}}
+SOLR_SSL_TRUST_STORE={{infra_solr_truststore_location}}
+SOLR_SSL_TRUST_STORE_PASSWORD={{infra_solr_truststore_password}}
+SOLR_SSL_NEED_CLIENT_AUTH=false
+SOLR_SSL_WANT_CLIENT_AUTH=false
+{% endif %}
+
+# Uncomment to set a specific SSL port (-Djetty.ssl.port=N); if not set
+# and you are using SSL, then the start script will use SOLR_PORT for the SSL port
+#SOLR_SSL_PORT=
+
+{% if security_enabled -%}
+SOLR_JAAS_FILE={{infra_solr_jaas_file}}
+SOLR_KERB_KEYTAB={{infra_solr_web_kerberos_keytab}}
+SOLR_KERB_PRINCIPAL={{infra_solr_web_kerberos_principal}}
+SOLR_OPTS="$SOLR_OPTS -Dsolr.hdfs.security.kerberos.principal={{infra_solr_kerberos_principal}}"
+SOLR_OPTS="$SOLR_OPTS {{zk_security_opts}}"
+
+SOLR_AUTH_TYPE="kerberos"
+SOLR_AUTHENTICATION_OPTS=" -DauthenticationPlugin=org.apache.solr.security.KerberosPlugin -Djava.security.auth.login.config=$SOLR_JAAS_FILE -Dsolr.kerberos.principal=${SOLR_KERB_PRINCIPAL} -Dsolr.kerberos.keytab=${SOLR_KERB_KEYTAB} -Dsolr.kerberos.cookie.domain=${SOLR_HOST}"
+{% endif %}

+ 42 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/properties/solr-client-log4j.properties.j2

@@ -0,0 +1,42 @@
+# Copyright 2011 The Apache Software Foundation
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+log4j.rootLogger=INFO,file,stdout,stderr
+
+log4j.appender.file=org.apache.log4j.RollingFileAppender
+log4j.appender.file.File={{solr_client_log|default('/var/log/ambari-infra-solr-client/solr-client.log')}}
+log4j.appender.file.MaxFileSize={{solr_client_log_maxfilesize}}MB
+log4j.appender.file.MaxBackupIndex={{solr_client_log_maxbackupindex}}
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d{DATE} %5p [%t] %c{1}:%L - %m%n
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Threshold=INFO
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%m%n
+log4j.appender.stdout.filter.lvlRangeFilter=org.apache.log4j.varia.LevelRangeFilter
+log4j.appender.stdout.filter.lvlRangeFilter.LevelMax=WARN
+
+log4j.appender.stderr=org.apache.log4j.ConsoleAppender
+log4j.appender.stderr.Threshold=ERROR
+log4j.appender.stderr.Target=System.err
+log4j.appender.stderr.layout=org.apache.log4j.PatternLayout
+log4j.appender.stderr.layout.ConversionPattern=%m%n
+log4j.appender.stderr.filter.lvlRangeFilter=org.apache.log4j.varia.LevelRangeFilter
+log4j.appender.stderr.filter.lvlRangeFilter.LevelMin=ERROR

+ 74 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/properties/solr-log4j2.xml.j2

@@ -0,0 +1,74 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<Configuration>
+  <Appenders>
+
+    <Console name="STDOUT" target="SYSTEM_OUT">
+      <PatternLayout>
+        <Pattern>
+          %d{ISO8601} [%t] %-5p [%X{collection} %X{shard} %X{replica} %X{core}] %C (%F:%L) - %m%n
+        </Pattern>
+      </PatternLayout>
+    </Console>
+
+    <RollingFile
+        name="RollingFile"
+        fileName="{{infra_solr_log_dir}}/solr.log"
+        filePattern="{{infra_solr_log_dir}}/solr.log.%i" >
+      <PatternLayout>
+        <Pattern>
+          %d{ISO8601} [%t] %-5p [%X{collection} %X{shard} %X{replica} %X{core}] %C (%F:%L) - %m%n
+        </Pattern>
+      </PatternLayout>
+      <Policies>
+        <OnStartupTriggeringPolicy />
+        <SizeBasedTriggeringPolicy size="{{infra_log_maxfilesize}} MB"/>
+      </Policies>
+      <DefaultRolloverStrategy max="{{infra_log_maxbackupindex}}"/>
+    </RollingFile>
+
+    <RollingFile
+        name="SlowFile"
+        fileName="{{infra_solr_log_dir}}/solr_slow_requests.log"
+        filePattern="{{infra_solr_log_dir}}/solr_slow_requests.log.%i" >
+      <PatternLayout>
+        <Pattern>
+          %d{ISO8601} [%t] %-5p [%X{collection} %X{shard} %X{replica} %X{core}] %C (%F:%L) - %m%n
+        </Pattern>
+      </PatternLayout>
+      <Policies>
+        <OnStartupTriggeringPolicy />
+        <SizeBasedTriggeringPolicy size="{{infra_log_maxfilesize}} MB"/>
+      </Policies>
+      <DefaultRolloverStrategy max="{{infra_log_maxbackupindex}}"/>
+    </RollingFile>
+
+  </Appenders>
+  <Loggers>
+    <Logger name="org.apache.hadoop" level="warn"/>
+    <Logger name="org.apache.solr.update.LoggingInfoStream" level="off"/>
+    <Logger name="org.apache.zookeeper" level="warn"/>
+    <Logger name="org.apache.solr.core.SolrCore.SlowRequest" level="warn" additivity="false">
+      <AppenderRef ref="SlowFile"/>
+    </Logger>
+
+    <Root level="warn">
+      <AppenderRef ref="RollingFile"/>
+      <!-- <AppenderRef ref="STDOUT"/> -->
+    </Root>
+  </Loggers>
+</Configuration>

+ 122 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/properties/solr.xml.j2

@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<solr>
+  <solrcloud>
+    <str name="host">${host:}</str>
+    <int name="hostPort">${jetty.port:}</int>
+    <str name="hostContext">${hostContext:solr}</str>
+    <int name="zkClientTimeout">${zkClientTimeout:15000}</int>
+    <bool name="genericCoreNodeNames">${genericCoreNodeNames:true}</bool>
+  </solrcloud>
+{% if metrics_enabled -%}
+  <metrics>
+    <reporter name="ambariInfra" group="jvm" class="org.apache.ambari.infra.solr.metrics.reporters.SimpleAMSReporter">
+      <int name="period">60</int>
+      <str name="amsCollectorHosts">{{ams_collector_hosts}}</str>
+      <int name="amsCollectorPort">{{ams_collector_port}}</int>
+      <str name="amsCollectorProtocol">{{ams_collector_protocol}}</str>
+      <str name="trustStoreLocation">{{infra_solr_truststore_location}}</str>
+      <str name="trustStoreType">{{infra_solr_truststore_type}}</str>
+      <str name="trustStorePassword">{{infra_solr_truststore_password}}</str>
+      <str name="filter">threads.count</str>
+      <str name="filter">threads.deadlock.count</str>
+      <str name="filter">memory.heap.used</str>
+      <str name="filter">memory.heap.max</str>
+      <str name="filter">memory.non-heap.used</str>
+      <str name="filter">memory.non-heap.max</str>
+      <str name="filter">memory.pools.CMS-Old-Gen.used</str>
+      <str name="filter">memory.pools.CMS-Old-Gen.max</str>
+      <str name="filter">gc.ConcurrentMarkSweep.count</str>
+      <str name="filter">gc.ConcurrentMarkSweep.time</str>
+      <str name="filter">gc.ParNew.count</str>
+      <str name="filter">gc.ParNew.time</str>
+      <str name="filter">memory.pools.Metaspace.used</str>
+      <str name="filter">memory.pools.Metaspace.max</str>
+      <str name="filter">memory.pools.Par-Eden-Space.used</str>
+      <str name="filter">memory.pools.Par-Eden-Space.max</str>
+      <str name="filter">memory.pools.Par-Survivor-Space.used</str>
+      <str name="filter">memory.pools.Par-Survivor-Space.max</str>
+      <str name="filter">gc.G1-Old-Generation.count</str>
+      <str name="filter">gc.G1-Old-Generation.time</str>
+      <str name="filter">gc.G1-Young-Generation.count</str>
+      <str name="filter">gc.G1-Young-Generation.time</str>
+      <str name="filter">memory.pools.G1-Eden-Space.used</str>
+      <str name="filter">memory.pools.G1-Eden-Space.max</str>
+      <str name="filter">memory.pools.G1-Survivor-Space.used</str>
+      <str name="filter">memory.pools.G1-Survivor-Space.max</str>
+      <str name="filter">os.processCpuLoad</str>
+      <str name="filter">os.systemCpuLoad</str>
+      <str name="filter">os.openFileDescriptorCount</str>
+    </reporter>
+  </metrics>
+  <metrics>
+    <reporter name="ambariInfraCore" group="core" class="org.apache.ambari.infra.solr.metrics.reporters.SimpleAMSReporter">
+      <int name="period">60</int>
+      <str name="amsCollectorHosts">{{ams_collector_hosts}}</str>
+      <int name="amsCollectorPort">{{ams_collector_port}}</int>
+      <str name="amsCollectorProtocol">{{ams_collector_protocol}}</str>
+      <str name="trustStoreLocation">{{infra_solr_truststore_location}}</str>
+      <str name="trustStoreType">{{infra_solr_truststore_type}}</str>
+      <str name="trustStorePassword">{{infra_solr_truststore_password}}</str>
+      <str name="filter">UPDATE.updateHandler.adds</str>
+      <str name="filter">UPDATE.updateHandler.deletesById</str>
+      <str name="filter">UPDATE.updateHandler.errors</str>
+      <str name="filter">UPDATE.updateHandler.docsPending</str>
+      <str name="filter">QUERY./select.requests</str>
+      <str name="filter">QUERY./select.requestTimes</str>
+      <str name="filter">UPDATE./update.requests</str>
+      <str name="filter">UPDATE./update.requestTimes</str>
+      <str name="filter">QUERY./get.requests</str>
+      <str name="filter">QUERY./get.requestTimes</str>
+      <str name="filter">ADMIN./admin/luke.requests</str>
+      <str name="filter">ADMIN./admin/luke.requestTimes</str>
+      <str name="filter">QUERY./query.requests</str>
+      <str name="filter">QUERY./query.requestTimes</str>
+      <str name="filter">INDEX.sizeInBytes</str>
+    </reporter>
+  </metrics>
+  <metrics>
+    <reporter name="ambariInfraCache" group="core" class="org.apache.ambari.infra.solr.metrics.reporters.AMSCacheReporter">
+      <int name="period">60</int>
+      <str name="amsCollectorHosts">{{ams_collector_hosts}}</str>
+      <int name="amsCollectorPort">{{ams_collector_port}}</int>
+      <str name="amsCollectorProtocol">{{ams_collector_protocol}}</str>
+      <str name="trustStoreLocation">{{infra_solr_truststore_location}}</str>
+      <str name="trustStoreType">{{infra_solr_truststore_type}}</str>
+      <str name="trustStorePassword">{{infra_solr_truststore_password}}</str>
+      <str name="filter">CACHE.searcher.filterCache</str>
+      <str name="filter">CACHE.searcher.queryResultCache</str>
+      <str name="filter">CACHE.searcher.documentCache</str>
+      <str name="fields">hitratio, size, warmupTime</str>
+    </reporter>
+  </metrics>
+  <metrics>
+    <reporter name="ambariInfraFieldCache" group="core" class="org.apache.ambari.infra.solr.metrics.reporters.AMSCacheReporter">
+      <int name="period">60</int>
+      <str name="amsCollectorHosts">{{ams_collector_hosts}}</str>
+      <int name="amsCollectorPort">{{ams_collector_port}}</int>
+      <str name="amsCollectorProtocol">{{ams_collector_protocol}}</str>
+      <str name="trustStoreLocation">{{infra_solr_truststore_location}}</str>
+      <str name="trustStoreType">{{infra_solr_truststore_type}}</str>
+      <str name="trustStorePassword">{{infra_solr_truststore_password}}</str>
+      <str name="filter">CACHE.core.fieldCache</str>
+      <str name="fields">entries_count</str>
+    </reporter>
+  </metrics>
+{% endif %}
+</solr>

+ 34 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/quicklinks/quicklinks.json

@@ -0,0 +1,34 @@
+{
+  "name": "default",
+  "description": "default quick links configuration",
+  "configuration": {
+    "protocol": {
+      "type":"https",
+      "checks":[
+        {
+          "property":"infra_solr_ssl_enabled",
+          "desired":"true",
+          "site":"infra-solr-env"
+        }
+      ]
+    },
+    "links": [
+      {
+        "name": "infra_solr_ui",
+        "label": "Solr Admin UI",
+        "component_name": "INFRA_SOLR",
+        "url": "%@://%@:%@",
+        "requires_user_name": "false",
+        "port": {
+          "http_property": "infra_solr_port",
+          "http_default_port": "8886",
+          "https_property": "infra_solr_port",
+          "https_default_port": "8886",
+          "regex": "^(\\d+)$",
+          "site": "infra-solr-env"
+        }
+      }
+    ]
+  }
+}
+

+ 7 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/role_command_order.json

@@ -0,0 +1,7 @@
+{
+  "general_deps" : {
+    "_comment" : "dependencies for AMBARI INFRA_SOLR",
+    "INFRA_SOLR-START" : ["ZOOKEEPER_SERVER-START"],
+    "AMBARI_INFRA_SOLR_SERVICE_CHECK-SERVICE_CHECK": ["INFRA_SOLR-START"]
+  }
+}

+ 129 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/service_advisor.py

@@ -0,0 +1,129 @@
+#!/usr/bin/env ambari-python-wrap
+"""
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+# Python imports
+import imp
+import os
+import traceback
+
+SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
+STACKS_DIR = os.path.join(SCRIPT_DIR, '../../../stacks/')
+PARENT_FILE = os.path.join(STACKS_DIR, 'service_advisor.py')
+if "BASE_SERVICE_ADVISOR" in os.environ:
+  PARENT_FILE = os.environ["BASE_SERVICE_ADVISOR"]
+
+try:
+  with open(PARENT_FILE, 'rb') as fp:
+    service_advisor = imp.load_module('service_advisor', fp, PARENT_FILE, ('.py', 'rb', imp.PY_SOURCE))
+except Exception as e:
+  traceback.print_exc()
+  print "Failed to load parent"
+
+class Ambari_Infra_SolrServiceAdvisor(service_advisor.ServiceAdvisor):
+
+  def __init__(self, *args, **kwargs):
+    self.as_super = super(Ambari_Infra_SolrServiceAdvisor, self)
+    self.as_super.__init__(*args, **kwargs)
+
+    # Always call these methods
+    self.modifyMastersWithMultipleInstances()
+    self.modifyCardinalitiesDict()
+    self.modifyHeapSizeProperties()
+    self.modifyNotValuableComponents()
+    self.modifyComponentsNotPreferableOnServer()
+    self.modifyComponentLayoutSchemes()
+
+  def modifyMastersWithMultipleInstances(self):
+    """
+    Modify the set of masters with multiple instances.
+    Must be overriden in child class.
+    """
+    # Nothing to do
+    pass
+
+  def modifyCardinalitiesDict(self):
+    """
+    Modify the dictionary of cardinalities.
+    Must be overriden in child class.
+    """
+    # Nothing to do
+    pass
+
+  def modifyHeapSizeProperties(self):
+    """
+    Modify the dictionary of heap size properties.
+    Must be overriden in child class.
+    """
+    pass
+
+  def modifyNotValuableComponents(self):
+    """
+    Modify the set of components whose host assignment is based on other services.
+    Must be overriden in child class.
+    """
+    # Nothing to do
+    pass
+
+  def modifyComponentsNotPreferableOnServer(self):
+    """
+    Modify the set of components that are not preferable on the server.
+    Must be overriden in child class.
+    """
+    # Nothing to do
+    pass
+
+  def modifyComponentLayoutSchemes(self):
+    """
+    Modify layout scheme dictionaries for components.
+    The scheme dictionary basically maps the number of hosts to
+    host index where component should exist.
+    Must be overriden in child class.
+    """
+    # Nothing to do
+    pass
+
+  def getServiceComponentLayoutValidations(self, services, hosts):
+    """
+    Get a list of errors.
+    Must be overriden in child class.
+    """
+
+    return self.getServiceComponentCardinalityValidations(services, hosts, "AMBARI_INFRA_SOLR")
+
+  def getServiceConfigurationRecommendations(self, configurations, clusterData, services, hosts):
+    """
+    Entry point.
+    Validate configurations for the service. Return a list of errors.
+    The code for this function should be the same for each Service Advisor.
+    """
+    #Logger.info("Class: %s, Method: %s. Validating Configurations." %
+    #            (self.__class__.__name__, inspect.stack()[0][3]))
+
+    pass
+
+  def getServiceConfigurationsValidationItems(self, configurations, recommendedDefaults, services, hosts):
+    """
+    Entry point.
+    Validate configurations for the service. Return a list of errors.
+    The code for this function should be the same for each Service Advisor.
+    """
+    #Logger.info("Class: %s, Method: %s. Validating Configurations." %
+    #            (self.__class__.__name__, inspect.stack()[0][3]))
+
+    return []

BIN
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/service_advisor.pyo


+ 127 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/themes/directories.json

@@ -0,0 +1,127 @@
+{
+  "name": "directories",
+  "description": "Directories theme for AMBARI_INFRA_SOLR service",
+  "configuration": {
+    "layouts": [
+      {
+        "name": "directories",
+        "tabs": [
+          {
+            "name": "directories",
+            "display-name": "Directories",
+            "layout": {
+              "tab-columns": "1",
+              "tab-rows": "4",
+              "sections": [
+                {
+                  "name": "subsection-data-dirs",
+                  "display-name": "DATA DIRS",
+                  "row-index": "0",
+                  "column-index": "0",
+                  "row-span": "1",
+                  "column-span": "1",
+                  "section-columns": "1",
+                  "section-rows": "1",
+                  "subsections": [
+                    {
+                      "name": "subsection-data-dirs",
+                      "row-index": "0",
+                      "column-index": "0",
+                      "row-span": "1",
+                      "column-span": "1"
+                    }
+                  ]
+                },
+                {
+                  "name": "subsection-log-dirs",
+                  "display-name": "LOG DIRS",
+                  "row-index": "1",
+                  "column-index": "0",
+                  "row-span": "1",
+                  "column-span": "1",
+                  "section-columns": "1",
+                  "section-rows": "1",
+                  "subsections": [
+                    {
+                      "name": "subsection-log-dirs",
+                      "row-index": "0",
+                      "column-index": "0",
+                      "row-span": "1",
+                      "column-span": "1"
+                    }
+                  ]
+                },
+                {
+                  "name": "subsection-pid-dirs",
+                  "display-name": "PID DIRS",
+                  "row-index": "2",
+                  "column-index": "0",
+                  "row-span": "1",
+                  "column-span": "1",
+                  "section-columns": "1",
+                  "section-rows": "1",
+                  "subsections": [
+                    {
+                      "name": "subsection-pid-dirs",
+                      "row-index": "0",
+                      "column-index": "0",
+                      "row-span": "1",
+                      "column-span": "1"
+                    }
+                  ]
+                }
+              ]
+            }
+          }
+        ]
+      }
+    ],
+    "placement": {
+      "configuration-layout": "default",
+      "configs": [
+        {
+          "config": "infra-solr-env/infra_solr_datadir",
+          "subsection-name": "subsection-data-dirs"
+        },
+        {
+          "config": "infra-solr-client-log4j/infra_solr_client_log_dir",
+          "subsection-name": "subsection-log-dirs"
+        },
+        {
+          "config": "infra-solr-env/infra_solr_log_dir",
+          "subsection-name": "subsection-log-dirs"
+        },
+        {
+          "config": "infra-solr-env/infra_solr_pid_dir",
+          "subsection-name": "subsection-pid-dirs"
+        }
+      ]
+    },
+    "widgets": [
+      {
+        "config": "infra-solr-env/infra_solr_datadir",
+        "widget": {
+          "type": "text-field"
+        }
+      },
+      {
+        "config": "infra-solr-client-log4j/infra_solr_client_log_dir",
+        "widget": {
+          "type": "text-field"
+        }
+      },
+      {
+        "config": "infra-solr-env/infra_solr_log_dir",
+        "widget": {
+          "type": "text-field"
+        }
+      },
+      {
+        "config": "infra-solr-env/infra_solr_pid_dir",
+        "widget": {
+          "type": "text-field"
+        }
+      }
+    ]
+  }
+}

+ 107 - 0
ambari-server/src/main/resources/common-services/AMBARI_INFRA_SOLR/3.0.0/themes/theme.json

@@ -0,0 +1,107 @@
+{
+  "name": "default",
+  "description": "Default theme for AMBARI_INFRA_SOLR service",
+  "configuration": {
+    "layouts": [
+      {
+        "name": "default",
+        "tabs": [
+          {
+            "name": "settings",
+            "display-name": "Settings",
+            "layout": {
+              "tab-columns": "2",
+              "tab-rows": "1",
+              "sections": [
+                {
+                  "name": "section-infra-solr",
+                  "display-name": "Ambari Infra Solr",
+                  "row-index": "0",
+                  "column-index": "0",
+                  "row-span": "1",
+                  "column-span": "1",
+                  "section-columns": "1",
+                  "section-rows": "4",
+                  "subsections": [
+                    {
+                      "name": "subsection-infra-solr-col1",
+                      "row-index": "0",
+                      "column-index": "0",
+                      "row-span": "1",
+                      "column-span": "1"
+                    },
+                    {
+                      "name": "subsection-infra-solr-col2",
+                      "row-index": "0",
+                      "column-index": "1",
+                      "row-span": "1",
+                      "column-span": "1"
+                    }
+                  ]
+                }
+              ]
+            }
+          }
+        ]
+      }
+    ],
+    "placement": {
+      "configuration-layout": "default",
+      "configs": [
+        {
+          "config": "infra-solr-env/infra_solr_minmem",
+          "subsection-name": "subsection-infra-solr-col1"
+        },
+        {
+          "config": "infra-solr-env/infra_solr_maxmem",
+          "subsection-name": "subsection-infra-solr-col1"
+        },
+        {
+          "config": "infra-solr-env/infra_solr_datadir",
+          "subsection-name": "subsection-infra-solr-col2"
+        },
+        {
+          "config": "infra-solr-env/infra_solr_znode",
+          "subsection-name": "subsection-infra-solr-col2"
+        }
+      ]
+    },
+    "widgets": [
+      {
+        "config": "infra-solr-env/infra_solr_minmem",
+        "widget": {
+          "type": "slider",
+          "units": [
+            {
+              "unit-name": "GB"
+            }
+          ]
+        }
+      },
+      {
+        "config": "infra-solr-env/infra_solr_maxmem",
+        "widget": {
+          "type": "slider",
+          "units": [
+            {
+              "unit-name": "GB"
+            }
+          ]
+        }
+      },
+      {
+        "config": "infra-solr-env/infra_solr_datadir",
+        "widget": {
+          "type": "directory"
+        }
+      },
+      {
+        "config": "infra-solr-env/infra_solr_znode",
+        "widget": {
+          "type": "directory"
+        }
+      }
+    ]
+  }
+}
+

+ 5 - 0
ambari-server/src/main/resources/stacks/BIGTOP/3.2.0/properties/stack_features.json

@@ -55,6 +55,11 @@
         "name": "kafka_listeners",
         "description": "Kafka listeners (AMBARI-10984)",
         "min_version": "3.2.0"
+      },
+      {
+        "name": "ranger_install_infra_client",
+        "description": "Ambari Infra Service support",
+        "min_version": "2.5.0.0"
       }
     ]
   }

+ 26 - 0
ambari-server/src/main/resources/stacks/BIGTOP/3.2.0/services/AMBARI_INFRA_SOLR/metainfo.xml

@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<metainfo>
+  <schemaVersion>2.0</schemaVersion>
+  <services>
+    <service>
+      <name>AMBARI_INFRA_SOLR</name>
+      <extends>common-services/AMBARI_INFRA_SOLR/3.0.0</extends>
+    </service>
+  </services>
+</metainfo>