You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@metron.apache.org by rm...@apache.org on 2018/02/22 20:14:29 UTC

[18/50] [abbrv] metron git commit: METRON-1370 Create Full Dev Equivalent for Ubuntu (nickwallen via cestella) closes apache/incubator-metron#903

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/extra_modules/ambari_service_state.py
----------------------------------------------------------------------
diff --git a/metron-deployment/extra_modules/ambari_service_state.py b/metron-deployment/extra_modules/ambari_service_state.py
deleted file mode 100644
index 6d44e8d..0000000
--- a/metron-deployment/extra_modules/ambari_service_state.py
+++ /dev/null
@@ -1,352 +0,0 @@
-#!/usr/bin/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.
-#
-
-DOCUMENTATION = '''
----
-module: ambari_service_state
-version_added: "2.1"
-author: Apache Metron (https://metron.apache.org)
-short_description: Start/Stop/Change Service or Component State
-description:
-    - Start/Stop/Change Service or Component State
-options:
-  host:
-    description:
-      The hostname for the ambari web server
-  port:
-    description:
-      The port for the ambari web server
-  username:
-    description:
-      The username for the ambari web server
-  password:
-    description:
-      The name of the cluster in web server
-    required: yes
-  cluster_name:
-    description:
-      The name of the cluster in ambari
-    required: yes
-  service_name:
-    description:
-      The name of the service to alter
-    required: no
-  component_name:
-    description:
-      The name of the component to alter
-    required: no
-  component_host:
-    description:
-      The host running the targeted component. Required when component_name is used.
-    required: no
-  state:
-    description:
-      The desired service/component state.
-  wait_for_complete:
-    description:
-      Whether to wait for the request to complete before returning. Default is False.
-    required: no
-  requirements: [ 'requests']
-'''
-
-EXAMPLES = '''
-# must use full relative path to any files in stored in roles/role_name/files/
-- name: Create a new ambari cluster
-    ambari_cluster_state:
-      host: localhost
-      port: 8080
-      username: admin
-      password: admin
-      cluster_name: my_cluster
-      cluster_state: present
-      blueprint_var: roles/my_role/files/blueprint.yml
-      blueprint_name: hadoop
-      wait_for_complete: True
-- name: Start the ambari cluster
-  ambari_cluster_state:
-    host: localhost
-    port: 8080
-    username: admin
-    password: admin
-    cluster_name: my_cluster
-    cluster_state: started
-    wait_for_complete: True
-- name: Stop the ambari cluster
-  ambari_cluster_state:
-    host: localhost
-    port: 8080
-    username: admin
-    password: admin
-    cluster_name: my_cluster
-    cluster_state: stopped
-    wait_for_complete: True
-- name: Delete the ambari cluster
-  ambari_cluster_state:
-    host: localhost
-    port: 8080
-    username: admin
-    password: admin
-    cluster_name: my_cluster
-    cluster_state: absent
-'''
-
-RETURN = '''
-results:
-    description: The content of the requests object returned from the RESTful call
-    returned: success
-    type: string
-'''
-
-__author__ = 'apachemetron'
-
-import json
-
-try:
-    import requests
-except ImportError:
-    REQUESTS_FOUND = False
-else:
-    REQUESTS_FOUND = True
-
-
-def main():
-
-    argument_spec = dict(
-        host=dict(type='str', default=None, required=True),
-        port=dict(type='int', default=None, required=True),
-        username=dict(type='str', default=None, required=True),
-        password=dict(type='str', default=None, required=True),
-        cluster_name=dict(type='str', default=None, required=True),
-        state=dict(type='str', default=None, required=True,
-                           choices=['started', 'stopped', 'deleted']),
-        service_name=dict(type='str', required=False),
-        component_name=dict(type='str', default=None, required=False),
-        component_host=dict(type='str', default=None, required=False),
-        wait_for_complete=dict(default=False, required=False, type='bool'),
-    )
-
-    required_together = ['component_name', 'component_host']
-
-    module = AnsibleModule(
-        argument_spec=argument_spec,
-        required_together=required_together
-    )
-
-    if not REQUESTS_FOUND:
-        module.fail_json(
-            msg='requests library is required for this module')
-
-    p = module.params
-
-    host = p.get('host')
-    port = p.get('port')
-    username = p.get('username')
-    password = p.get('password')
-    cluster_name = p.get('cluster_name')
-    state = p.get('state')
-    service_name = p.get('service_name')
-    component_name = p.get('component_name')
-    component_host = p.get('component_host')
-    wait_for_complete = p.get('wait_for_complete')
-    component_mode = False
-    ambari_url = 'http://{0}:{1}'.format(host, port)
-
-    if component_name:
-        component_mode = True
-
-    try:
-        if not cluster_exists(ambari_url, username, password, cluster_name):
-            module.fail_json(msg="Cluster name {0} does not exist".format(cluster_name))
-
-        if state in ['started', 'stopped', 'installed']:
-            desired_state = ''
-
-            if state == 'started':
-                desired_state = 'STARTED'
-            elif state in ['stopped','installed']:
-                desired_state = 'INSTALLED'
-
-            if component_mode:
-                if desired_state == 'INSTALLED':
-                    if(can_add_component(ambari_url, username, password, cluster_name, component_name, component_host)):
-                        add_component_to_host(ambari_url, username, password, cluster_name, component_name, component_host)
-                request = set_component_state(ambari_url, username, password, cluster_name, component_name, component_host, desired_state)
-            else:
-                request = set_service_state(ambari_url,username,password,cluster_name,service_name, desired_state)
-            if wait_for_complete:
-                try:
-                    request_id = json.loads(request.content)['Requests']['id']
-                except ValueError:
-                    module.exit_json(changed=True, results=request.content)
-                status = wait_for_request_complete(ambari_url, username, password, cluster_name, request_id, 2)
-                if status != 'COMPLETED':
-                    module.fail_json(msg="Request failed with status {0}".format(status))
-            module.exit_json(changed=True, results=request.content)
-
-        elif state == 'deleted':
-            if component_mode:
-                request = delete_component(ambari_url, username, password, cluster_name, component_name, component_host)
-            else:
-                request = delete_service(ambari_url,username,password,cluster_name,service_name)
-            module.exit_json(changed=True, results=request.content)
-
-    except requests.ConnectionError, e:
-        module.fail_json(msg="Could not connect to Ambari client: " + str(e.message))
-    except Exception, e:
-        module.fail_json(msg="Ambari client exception occurred: " + str(e.message))
-
-
-def get_clusters(ambari_url, user, password):
-    r = get(ambari_url, user, password, '/api/v1/clusters')
-    if r.status_code != 200:
-        msg = 'Could not get cluster list: request code {0}, \
-                    request message {1}'.format(r.status_code, r.content)
-        raise Exception(msg)
-    clusters = json.loads(r.content)
-    return clusters['items']
-
-
-def cluster_exists(ambari_url, user, password, cluster_name):
-    clusters = get_clusters(ambari_url, user, password)
-    return cluster_name in [item['Clusters']['cluster_name'] for item in clusters]
-
-
-def get_request_status(ambari_url, user, password, cluster_name, request_id):
-    path = '/api/v1/clusters/{0}/requests/{1}'.format(cluster_name, request_id)
-    r = get(ambari_url, user, password, path)
-    if r.status_code != 200:
-        msg = 'Could not get cluster request status: request code {0}, \
-                    request message {1}'.format(r.status_code, r.content)
-        raise Exception(msg)
-    service = json.loads(r.content)
-    return service['Requests']['request_status']
-
-
-def wait_for_request_complete(ambari_url, user, password, cluster_name, request_id, sleep_time):
-    while True:
-        status = get_request_status(ambari_url, user, password, cluster_name, request_id)
-        if status == 'COMPLETED':
-            return status
-        elif status in ['FAILED', 'TIMEDOUT', 'ABORTED', 'SKIPPED_FAILED']:
-            return status
-        else:
-            time.sleep(sleep_time)
-
-
-def set_service_state(ambari_url, user, password, cluster_name, service_name, desired_state):
-    path = '/api/v1/clusters/{0}/services/{1}'.format(cluster_name,service_name)
-    request = {"RequestInfo": {"context": "Setting {0} to {1} via REST".format(service_name,desired_state)},
-               "Body": {"ServiceInfo": {"state": "{0}".format(desired_state)}}}
-    payload = json.dumps(request)
-    r = put(ambari_url, user, password, path, payload)
-    if r.status_code not in [202, 200]:
-        msg = 'Could not set service state: request code {0}, \
-                    request message {1}'.format(r.status_code, r.content)
-        raise Exception(msg)
-    return r
-
-
-def set_component_state(ambari_url, user, password, cluster_name, component_name, component_host, desired_state):
-    path = '/api/v1/clusters/{0}/hosts/{1}/host_components/{2}'.format(cluster_name,component_host,component_name)
-    request = {"RequestInfo": {"context": "Setting {0} to {1} via REST".format(component_name,desired_state)},
-               "Body": {"HostRoles": {"state": "{0}".format(desired_state)}}}
-    payload = json.dumps(request)
-    r = put(ambari_url, user, password, path, payload)
-    if r.status_code not in [202, 200]:
-        msg = 'Could not set component state: request code {0}, \
-                    request message {1}'.format(r.status_code, r.content)
-        raise Exception(msg)
-    return r
-
-
-def delete_component(ambari_url, user, password, cluster_name, component_name, component_host):
-    enable_maint_mode(ambari_url, user, password, cluster_name, component_name, component_host)
-    path = '/api/v1/clusters/{0}/hosts/{1}/host_components/{2}'.format(cluster_name,component_host,component_name)
-    r = delete(ambari_url,user,password,path)
-    if r.status_code not in [202, 200]:
-        msg = 'Could not set service state: request code {0}, \
-                    request message {1}'.format(r.status_code, r.content)
-        raise Exception(msg)
-    return r
-
-
-def enable_maint_mode(ambari_url, user, password, cluster_name, component_name, component_host):
-    path = '/api/v1/clusters/{0}/hosts/{1}/host_components/{2}'.format(cluster_name,component_host,component_name)
-    request = {"RequestInfo":{"context":"Turn On Maintenance Mode for {0}".format(component_name)},
-               "Body":{"HostRoles":{"maintenance_state":"ON"}}}
-    payload = json.dumps(request)
-    r = put(ambari_url, user, password, path, payload)
-    if r.status_code not in [202, 200]:
-        msg = 'Could not set maintenance mode: request code {0}, \
-                    request message {1}'.format(r.status_code, r.content)
-        raise Exception(msg)
-    return r
-
-
-def delete_service(ambari_url, user, password, cluster_name, service_name):
-    path = '/api/v1/clusters/{0}/services/{1}'.format(cluster_name,service_name)
-    r = delete(ambari_url,user,password,path)
-    if r.status_code not in [202, 200]:
-        msg = 'Could not delete service: request code {0}, \
-                    request message {1}'.format(r.status_code, r.content)
-        raise Exception(msg)
-    return r
-
-
-def add_component_to_host(ambari_url, user, password, cluster_name, component_name, component_host):
-    path = '/api/v1/clusters/{0}/hosts/{1}/host_components/{2}'.format(cluster_name,component_host,component_name)
-    r = post(ambari_url, user, password, path,'')
-    if r.status_code not in [202,201,200]:
-        msg = 'Could not add {0} to host {1}: request code {2}, \
-                    request message {3}'.format(component_name,component_host,r.status_code, r.content)
-        raise Exception(msg)
-    return r
-
-
-def can_add_component(ambari_url, user, password, cluster_name, component_name, component_host):
-    path = '/api/v1/clusters/{0}/hosts/{1}/host_components/{2}'.format(cluster_name,component_host,component_name)
-    r = get(ambari_url, user, password, path)
-    return r.status_code == 404
-
-
-def get(ambari_url, user, password, path):
-    r = requests.get(ambari_url + path, auth=(user, password))
-    return r
-
-
-def put(ambari_url, user, password, path, data):
-    headers = {'X-Requested-By': 'ambari'}
-    r = requests.put(ambari_url + path, data=data, auth=(user, password), headers=headers)
-    return r
-
-
-def post(ambari_url, user, password, path, data):
-    headers = {'X-Requested-By': 'ambari'}
-    r = requests.post(ambari_url + path, data=data, auth=(user, password), headers=headers)
-    return r
-
-
-def delete(ambari_url, user, password, path):
-    headers = {'X-Requested-By': 'ambari'}
-    r = requests.delete(ambari_url + path, auth=(user, password), headers=headers)
-    return r
-
-
-from ansible.module_utils.basic import *
-if __name__ == '__main__':
-    main()

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/inventory/full-dev-platform/group_vars/all
----------------------------------------------------------------------
diff --git a/metron-deployment/inventory/full-dev-platform/group_vars/all b/metron-deployment/inventory/full-dev-platform/group_vars/all
deleted file mode 100644
index c07278b..0000000
--- a/metron-deployment/inventory/full-dev-platform/group_vars/all
+++ /dev/null
@@ -1,89 +0,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.
-#
-
-# which services should be started?
-services_to_start:
-  - snort
-  - snort-logs
-  - bro
-  - pcap-replay
-
-# ambari
-ambari_host: "{{ groups.ambari_master[0] }}"
-hdp_host_group: "{{ groups.ambari_slave }}"
-ambari_port: 8080
-ambari_user: admin
-ambari_password: admin
-cluster_type: single_node_vm
-ambari_server_mem: 512
-java_home: /usr/jdk64/jdk1.8.0_77
-
-# hbase
-pcap_hbase_table: pcap
-tracker_hbase_table: access_tracker
-threatintel_hbase_table: threatintel
-enrichment_hbase_table: enrichment
-
-# metron
-metron_version: 0.4.3
-metron_directory: /usr/metron/{{ metron_version }}
-bro_version: "2.5.2"
-fixbuf_version: "1.7.1"
-yaf_version: "2.8.0"
-daq_version: "2.0.6-1"
-pycapa_repo: "https://github.com/OpenSOC/pycapa.git"
-pycapa_home: "/opt/pycapa"
-snort_version: "2.9.8.0-1"
-snort_alert_csv_path: "/var/log/snort/alert.csv"
-threat_intel_bulk_load: False
-
-# data directories - only required to override defaults
-zookeeper_data_dir: "/data1/hadoop/zookeeper"
-namenode_checkpoint_dir: "/data1/hadoop/hdfs/namesecondary"
-namenode_name_dir: "/data1/hadoop/hdfs/namenode"
-datanode_data_dir: "/data1/hadoop/hdfs/data,/data2/hadoop/hdfs/data"
-journalnode_edits_dir: "/data1/hadoop/hdfs/journalnode"
-nodemanager_local_dirs: "/data1/hadoop/yarn/local"
-timeline_ldb_store_path: "/data1/hadoop/yarn/timeline"
-timeline_ldb_state_path: "/data1/hadoop/yarn/timeline"
-nodemanager_log_dirs: "/data1/hadoop/yarn/log"
-jhs_recovery_store_ldb_path: "/data1/hadoop/mapreduce/jhs"
-storm_local_dir: "/data1/hadoop/storm"
-kafka_log_dirs: "/data1/kafka-log"
-elasticsearch_data_dir: "/data1/elasticsearch,/data2/elasticsearch"
-
-# sensors
-sensor_test_mode: True
-install_pycapa: False
-install_bro: True
-install_snort: True
-install_yaf: False
-install_pcap_replay: True
-sniff_interface: eth1
-pcap_replay_interface: "{{ sniff_interface }}"
-pcapservice_port: 8081
-
-# search
-install_elasticsearch: True
-install_solr: False
-solr_collection_name: Metron
-solr_number_shards: 1
-solr_replication_factor: 1
-elasticsearch_transport_port: 9300
-## The elasticsearch_network_interface must be in the form specified for Elasticsearch, with leading and trailing underscores.
-elasticsearch_network_interface: _eth1_
-elasticsearch_web_port: 9200

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/inventory/full-dev-platform/hosts
----------------------------------------------------------------------
diff --git a/metron-deployment/inventory/full-dev-platform/hosts b/metron-deployment/inventory/full-dev-platform/hosts
deleted file mode 100644
index 9bd9ea1..0000000
--- a/metron-deployment/inventory/full-dev-platform/hosts
+++ /dev/null
@@ -1,47 +0,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.
-#
-
-[ambari_master]
-node1
-
-[ambari_slave]
-node1
-
-[metron]
-node1
-
-[search]
-node1
-
-[sensors]
-node1
-
-[pcap_server]
-node1
-
-[web]
-node1
-
-[zeppelin]
-node1
-
-[monit:children]
-sensors
-pcap_server
-
-[local]
-127.0.0.1

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/addon-services/METRON/CURRENT/repos/repoinfo.xml
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/addon-services/METRON/CURRENT/repos/repoinfo.xml b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/addon-services/METRON/CURRENT/repos/repoinfo.xml
index fac4f77..9b1888c 100644
--- a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/addon-services/METRON/CURRENT/repos/repoinfo.xml
+++ b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/addon-services/METRON/CURRENT/repos/repoinfo.xml
@@ -28,5 +28,11 @@
             <reponame>METRON</reponame>
         </repo>
     </os>
+    <os family="ubuntu14">
+        <repo>
+            <baseurl>file:///localrepo</baseurl>
+            <repoid>METRON-${metron.version}</repoid>
+            <reponame>METRON</reponame>
+        </repo>
+    </os>
 </reposinfo>
-

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/configuration/elastic-sysconfig.xml
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/configuration/elastic-sysconfig.xml b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/configuration/elastic-sysconfig.xml
index d6db027..cb069b8 100755
--- a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/configuration/elastic-sysconfig.xml
+++ b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/configuration/elastic-sysconfig.xml
@@ -55,10 +55,10 @@
         <description>Maximum number of memory map areas for process</description>
     </property>
 
-    <!--/etc/sysconfig/elasticsearch-->
+    <!-- Elasticsearch sysconfig -->
     <property>
         <name>content</name>
-        <description>This is the jinja template for elastic sysconfig file (/etc/sysconfig/elasticsearch)</description>
+        <description>This is the jinja template for elastic sysconfig file</description>
         <value>
 # Directory where the Elasticsearch binary distribution resides
 ES_HOME={{elastic_home}}
@@ -97,6 +97,9 @@ ES_JAVA_OPTS="-verbose:gc -Xloggc:{{log_dir}}/elasticsearch_gc.log -XX:-CMSConcu
 -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps \
 -XX:ErrorFile={{log_dir}}/elasticsearch_err.log -XX:ParallelGCThreads=8 \
 -Xms{{heap_size}} -Xmx{{heap_size}}"
+
+# https://www.elastic.co/guide/en/elasticsearch/reference/5.6/_memory_lock_check.html
+MAX_LOCKED_MEMORY=unlimited
         </value>
     </property>
 </configuration>

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/configuration/elastic-systemd.xml
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/configuration/elastic-systemd.xml b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/configuration/elastic-systemd.xml
new file mode 100644
index 0000000..311e3c0
--- /dev/null
+++ b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/configuration/elastic-systemd.xml
@@ -0,0 +1,30 @@
+<?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>
+    <property>
+        <name>content</name>
+        <description>The jinja template for the Elasticsearch systemd override file.  Applies only to platforms that use systemd.</description>
+        <value>
+[Service]
+LimitMEMLOCK=infinity
+        </value>
+    </property>
+</configuration>

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/metainfo.xml
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/metainfo.xml b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/metainfo.xml
index 3783d31..0943eec 100755
--- a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/metainfo.xml
+++ b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/metainfo.xml
@@ -49,13 +49,29 @@
             </components>
             <osSpecifics>
                 <osSpecific>
-                    <osFamily>any</osFamily>
+                    <osFamily>redhat6</osFamily>
                     <packages>
                         <package>
                             <name>elasticsearch-5.6.2</name>
                         </package>
                     </packages>
                 </osSpecific>
+                <osSpecific>
+                    <osFamily>redhat7</osFamily>
+                    <packages>
+                        <package>
+                            <name>elasticsearch-5.6.2</name>
+                        </package>
+                    </packages>
+                </osSpecific>
+                <osSpecific>
+                    <osFamily>ubuntu14</osFamily>
+                    <packages>
+                        <package>
+                            <name>elasticsearch=5.6.2</name>
+                        </package>
+                    </packages>
+                </osSpecific>
             </osSpecifics>
             <commandScript>
                 <script>scripts/service_check.py</script>
@@ -66,6 +82,7 @@
                 <config-type>elastic-env</config-type>
                 <config-type>elastic-site</config-type>
                 <config-type>elastic-sysconfig</config-type>
+                <config-type>elastic-systemd</config-type>
             </configuration-dependencies>
             <restartRequiredAfterChange>true</restartRequiredAfterChange>
             <quickLinksConfigurations>

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/elastic.py
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/elastic.py b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/elastic.py
deleted file mode 100755
index e27e8bf..0000000
--- a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/elastic.py
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/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 resource_management.core.resources.system import Directory
-from resource_management.core.resources.system import File
-from resource_management.core.source import InlineTemplate
-from resource_management.core.source import Template
-from resource_management.core.resources import User
-from resource_management.core.logger import Logger
-from resource_management.libraries.functions import format as ambari_format
-
-def elastic():
-    import params
-
-    Logger.info("Creating user: {0}:{1}".format(params.elastic_user, params.elastic_group))
-    User(params.elastic_user, action = "create", groups = params.elastic_group)
-
-    params.path_data = params.path_data.replace('"', '')
-    data_path = params.path_data.replace(' ', '').split(',')
-    data_path[:] = [x.replace('"', '') for x in data_path]
-    directories = [params.log_dir, params.pid_dir, params.conf_dir]
-    directories = directories + data_path + ["{0}/scripts".format(params.conf_dir)]
-
-    Logger.info("Creating directories: {0}".format(directories))
-    Directory(directories,
-              create_parents=True,
-              mode=0755,
-              owner=params.elastic_user,
-              group=params.elastic_group
-              )
-
-    Logger.info("Master env: ""{0}/elastic-env.sh".format(params.conf_dir))
-    File("{0}/elastic-env.sh".format(params.conf_dir),
-         owner=params.elastic_user,
-         group=params.elastic_group,
-         content=InlineTemplate(params.elastic_env_sh_template)
-         )
-
-    configurations = params.config['configurations']['elastic-site']
-    Logger.info("Master yml: ""{0}/elasticsearch.yml".format(params.conf_dir))
-    File("{0}/elasticsearch.yml".format(params.conf_dir),
-         content=Template(
-             "elasticsearch.master.yaml.j2",
-             configurations=configurations),
-         owner=params.elastic_user,
-         group=params.elastic_group
-         )
-
-    Logger.info("Master sysconfig: /etc/sysconfig/elasticsearch")
-    File("/etc/sysconfig/elasticsearch",
-         owner="root",
-         group="root",
-         content=InlineTemplate(params.sysconfig_template)
-         )
-
-    # in some OS this folder may not exist, so create it
-    Logger.info("Ensure PAM limits directory exists: {0}".format(params.limits_conf_dir))
-    Directory(params.limits_conf_dir,
-              create_parents=True,
-              owner='root',
-              group='root'
-    )
-
-    Logger.info("Master PAM limits: {0}".format(params.limits_conf_file))
-    File(params.limits_conf_file,
-         content=Template('elasticsearch_limits.conf.j2'),
-         owner="root",
-         group="root"
-         )

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/elastic_commands.py
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/elastic_commands.py b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/elastic_commands.py
new file mode 100644
index 0000000..afbaff2
--- /dev/null
+++ b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/elastic_commands.py
@@ -0,0 +1,253 @@
+#!/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.
+
+"""
+
+import os
+
+from ambari_commons.os_check import OSCheck
+from resource_management.core.exceptions import ExecutionFailed
+from resource_management.core.exceptions import ComponentIsNotRunning
+from resource_management.core.resources.system import Execute
+from resource_management.core.resources.system import Directory
+from resource_management.core.resources.system import File
+from resource_management.core.source import InlineTemplate
+from resource_management.core.source import Template
+from resource_management.core.resources import User
+from resource_management.core.logger import Logger
+from resource_management.libraries.functions import format as ambari_format
+from resource_management.libraries.functions.get_user_call_output import get_user_call_output
+
+
+def service_check(cmd, user, label):
+    """
+    Executes a SysV service check command that adheres to LSB-compliant
+    return codes.  The return codes are interpreted as defined
+    by the LSB.
+
+    See http://refspecs.linuxbase.org/LSB_3.0.0/LSB-PDA/LSB-PDA/iniscrptact.html
+    for more information.
+
+    :param cmd: The service check command to execute.
+    :param label: The name of the service.
+    """
+    Logger.info("Performing service check; cmd={0}, user={1}, label={2}".format(cmd, user, label))
+    rc, out, err = get_user_call_output(cmd, user, is_checked_call=False)
+
+    if rc in [1, 2, 3]:
+      # if return code in [1, 2, 3], then 'program is not running' or 'program is dead'
+      Logger.info("{0} is not running".format(label))
+      raise ComponentIsNotRunning()
+
+    elif rc == 0:
+      # if return code = 0, then 'program is running or service is OK'
+      Logger.info("{0} is running".format(label))
+
+    else:
+      # else service state is unknown
+      err_msg = "{0} service check failed; cmd '{1}' returned {2}".format(label, cmd, rc)
+      Logger.error(err_msg)
+      raise ExecutionFailed(err_msg, rc, out, err)
+
+def is_systemd_running():
+    """
+    Determines if the platform is running Systemd.
+    :return True, if the platform is running Systemd.  False, otherwise.
+    """
+    Logger.info("Is the platform running Systemd?")
+    rc, out, err = get_user_call_output("pidof systemd", "root", is_checked_call=False)
+    if rc == 0:
+        Logger.info("Systemd was found")
+        return True
+    else:
+        Logger.info("Systemd was NOT found")
+        return False
+
+def configure_systemd(params):
+    """
+    Configure Systemd for Elasticsearch.
+    """
+    Logger.info("Configuring Systemd for Elasticsearch");
+
+    # ensure the systemd directory for elasticsearch overrides exists
+    Logger.info("Create Systemd directory for Elasticsearch: {0}".format(params.systemd_elasticsearch_dir))
+    Directory(params.systemd_elasticsearch_dir,
+              create_parents=True,
+              owner='root',
+              group='root')
+
+    # when using Elasticsearch packages on systems that use systemd, system
+    # limits must also be specified via systemd.
+    # see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/setting-system-settings.html#systemd
+    Logger.info("Elasticsearch systemd limits: {0}".format(params.systemd_override_file))
+    File(params.systemd_override_file,
+         content=InlineTemplate(params.systemd_override_template),
+         owner="root",
+         group="root")
+
+    # reload the configuration
+    Execute("systemctl daemon-reload")
+
+def create_user(params):
+    """
+    Creates the user required for Elasticsearch.
+    """
+    Logger.info("Creating user={0} in group={1}".format(params.elastic_user, params.elastic_group))
+    User(params.elastic_user, action = "create", groups = params.elastic_group)
+
+def create_directories(params, directories):
+    """
+    Creates one or more directories.
+    """
+    Logger.info("Creating directories: {0}".format(directories))
+    Directory(directories,
+              create_parents=True,
+              mode=0755,
+              owner=params.elastic_user,
+              group=params.elastic_group
+              )
+
+def create_elastic_env(params):
+    """
+    Creates the Elasticsearch environment file.
+    """
+    Logger.info("Create Elasticsearch environment file.")
+    File("{0}/elastic-env.sh".format(params.conf_dir),
+         owner=params.elastic_user,
+         group=params.elastic_group,
+         content=InlineTemplate(params.elastic_env_sh_template))
+
+def create_elastic_site(params, template_name):
+    """
+    Creates the Elasticsearch site file.
+    """
+    Logger.info("Creating Elasticsearch site file; template={0}".format(template_name))
+
+    elastic_site = params.config['configurations']['elastic-site']
+    path = "{0}/elasticsearch.yml".format(params.conf_dir)
+    template = Template(template_name, configurations=elastic_site)
+    File(path,
+         content=template,
+         owner=params.elastic_user,
+         group=params.elastic_group)
+
+def get_elastic_config_path(default="/etc/default/elasticsearch"):
+    """
+    Defines the path to the Elasticsearch environment file.  This path will
+    differ based on the OS family.
+    :param default: The path used if the OS family is not recognized.
+    """
+    path = default
+    if OSCheck.is_redhat_family():
+      path = "/etc/sysconfig/elasticsearch"
+    elif OSCheck.is_ubuntu_family():
+      path = "/etc/default/elasticsearch"
+    else:
+      Logger.error("Unexpected OS family; using default path={0}".format(path))
+
+    return path
+
+def create_elastic_config(params):
+    """
+    Creates the Elasticsearch system config file.  Usually lands at either
+    /etc/sysconfig/elasticsearch or /etc/default/elasticsearch.
+    """
+    path = get_elastic_config_path()
+    Logger.info("Creating the Elasticsearch system config; path={0}".format(path))
+    File(path, owner="root", group="root", content=InlineTemplate(params.sysconfig_template))
+
+def create_elastic_pam_limits(params):
+    """
+    Creates the PAM limits for Elasticsearch.
+    """
+    Logger.info("Creating Elasticsearch PAM limits.")
+
+    # in some OS this folder may not exist, so create it
+    Logger.info("Ensure PAM limits directory exists: {0}".format(params.limits_conf_dir))
+    Directory(params.limits_conf_dir,
+              create_parents=True,
+              owner='root',
+              group='root')
+
+    Logger.info("Creating Elasticsearch PAM limits; file={0}".format(params.limits_conf_file))
+    File(params.limits_conf_file,
+         content=Template('elasticsearch_limits.conf.j2'),
+         owner="root",
+         group="root")
+
+def get_data_directories(params):
+    """
+    Returns the directories to use for storing Elasticsearch data.
+    """
+    path = params.path_data
+    path = path.replace('"', '')
+    path = path.replace(' ', '')
+    path = path.split(',')
+    dirs = [p.replace('"', '') for p in path]
+
+    Logger.info("Elasticsearch data directories: dirs={0}".format(dirs))
+    return dirs
+
+def configure_master():
+    """
+    Configures the Elasticsearch master node.
+    """
+    import params
+
+    # define the directories required
+    dirs = [
+      params.log_dir,
+      params.pid_dir,
+      params.conf_dir,
+      "{0}/scripts".format(params.conf_dir)
+    ]
+    dirs += get_data_directories(params)
+
+    # configure the elasticsearch master
+    create_user(params)
+    create_directories(params, dirs)
+    create_elastic_env(params)
+    create_elastic_site(params,  "elasticsearch.master.yaml.j2")
+    create_elastic_config(params)
+    create_elastic_pam_limits(params)
+    if is_systemd_running():
+        configure_systemd(params)
+
+def configure_slave():
+    """
+    Configures the Elasticsearch slave node.
+    """
+    import params
+
+    # define the directories required
+    dirs = [
+      params.log_dir,
+      params.pid_dir,
+      params.conf_dir,
+    ]
+    dirs += get_data_directories(params)
+
+    # configure the elasticsearch slave
+    create_user(params)
+    create_directories(params, dirs)
+    create_elastic_env(params)
+    create_elastic_site(params, "elasticsearch.slave.yaml.j2")
+    create_elastic_config(params)
+    create_elastic_pam_limits(params)
+    if is_systemd_running():
+        configure_systemd(params)

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/elastic_master.py
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/elastic_master.py b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/elastic_master.py
index 3e299e7..142ce4e 100755
--- a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/elastic_master.py
+++ b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/elastic_master.py
@@ -21,13 +21,11 @@ from resource_management.core import shell
 from resource_management.core.resources.system import Execute
 from resource_management.libraries.script import Script
 from resource_management.core.logger import Logger
-
-from resource_management.core.exceptions import ExecutionFailed
-from resource_management.core.exceptions import ComponentIsNotRunning
-from elastic import elastic
-
+from elastic_commands import service_check
+from elastic_commands import configure_master
 
 class Elasticsearch(Script):
+
     def install(self, env):
         import params
         env.set_params(params)
@@ -38,57 +36,36 @@ class Elasticsearch(Script):
         import params
         env.set_params(params)
         Logger.info('Configure Elasticsearch master node')
-        elastic()
+        configure_master()
 
     def stop(self, env, upgrade_type=None):
         import params
         env.set_params(params)
         Logger.info('Stop Elasticsearch master node')
-        stop_cmd = "service elasticsearch stop"
-        Execute(stop_cmd)
+        Execute("service elasticsearch stop")
 
     def start(self, env, upgrade_type=None):
         import params
         env.set_params(params)
         Logger.info('Start Elasticsearch master node')
         self.configure(env)
-        start_cmd = "service elasticsearch start"
-        Execute(start_cmd)
+        Execute("service elasticsearch start")
 
     def status(self, env):
         import params
         env.set_params(params)
-        Logger.info('Check status of Elasticsearch master node')
-
-        # return codes defined by LSB
-        # http://refspecs.linuxbase.org/LSB_3.0.0/LSB-PDA/LSB-PDA/iniscrptact.html
-        cmd = ('service', 'elasticsearch', 'status')
-	
-        rc, out = shell.call(cmd, sudo=True, quiet=False)
-
-        if rc in [1, 2, 3]:
-          # if return code = 1, 2, or 3, then 'program is not running' or 'dead'
-          # Ambari's resource_management/libraries/script/script.py handles
-          # this specific exception as OK
-          Logger.info("Elasticsearch master is not running")
-          raise ComponentIsNotRunning()
-
-        elif rc == 0:
-          # if return code = 0, then 'program is running or service is OK'
-          Logger.info("Elasticsearch master is running")
-
-        else:
-          # else, program is dead or service state is unknown
-          err_msg = "Execution of '{0}' returned {1}".format(" ".join(cmd), rc)
-          raise ExecutionFailed(err_msg, rc, out)
+        Logger.info('Status check Elasticsearch master node')
+        service_check(
+          cmd="service elasticsearch status",
+          user=params.elastic_status_check_user,
+          label="Elasticsearch Master")
 
     def restart(self, env):
         import params
         env.set_params(params)
-        self.configure(env)
         Logger.info('Restart Elasticsearch master node')
-        restart_cmd = "service elasticsearch restart"
-        Execute(restart_cmd)
+        self.configure(env)
+        Execute("service elasticsearch restart")
 
 
 if __name__ == "__main__":

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/elastic_slave.py
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/elastic_slave.py b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/elastic_slave.py
index d7684f0..2d559ff 100755
--- a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/elastic_slave.py
+++ b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/elastic_slave.py
@@ -17,77 +17,54 @@ limitations under the License.
 
 """
 
-from resource_management.core import shell
-from resource_management.core.exceptions import ExecutionFailed
-from resource_management.core.exceptions import ComponentIsNotRunning
 from resource_management.core.logger import Logger
 from resource_management.core.resources.system import Execute
 from resource_management.libraries.script import Script
 
-from slave import slave
-
+from elastic_commands import service_check
+from elastic_commands import configure_slave
 
 class Elasticsearch(Script):
+
     def install(self, env):
         import params
         env.set_params(params)
-        Logger.info('Install Elasticsearch data node')
+        Logger.info('Install Elasticsearch slave node')
         self.install_packages(env)
 
     def configure(self, env, upgrade_type=None, config_dir=None):
         import params
         env.set_params(params)
-        Logger.info('Configure Elasticsearch data node')
-        slave()
+        Logger.info('Configure Elasticsearch slave node')
+        configure_slave()
 
     def stop(self, env, upgrade_type=None):
         import params
         env.set_params(params)
-        Logger.info('Stop Elasticsearch data node')
-        stop_cmd = "service elasticsearch stop"
-        Execute(stop_cmd)
+        Logger.info('Stop Elasticsearch slave node')
+        Execute("service elasticsearch stop")
 
     def start(self, env, upgrade_type=None):
         import params
         env.set_params(params)
         self.configure(env)
-        Logger.info('Start Elasticsearch data node')
-        start_cmd = "service elasticsearch start"
-        Execute(start_cmd)
+        Execute("service elasticsearch start")
 
     def status(self, env):
         import params
         env.set_params(params)
-        Logger.info('Check status of Elasticsearch data node')
-
-        # return codes defined by LSB
-        # http://refspecs.linuxbase.org/LSB_3.0.0/LSB-PDA/LSB-PDA/iniscrptact.html
-        cmd = ('service', 'elasticsearch', 'status')
-        rc, out = shell.call(cmd, sudo=True, quiet=False)
-
-        if rc in [1, 2, 3]:
-          # if return code = 1, 2, or 3, then 'program is not running' or 'dead'
-          # Ambari's resource_management/libraries/script/script.py handles
-          # this specific exception as OK
-          Logger.info("Elasticsearch slave is not running")
-          raise ComponentIsNotRunning()
-
-        elif rc == 0:
-          # if return code = 0, then 'program is running or service is OK'
-          Logger.info("Elasticsearch slave is running")
-
-        else:
-          # else, program is dead or service state is unknown
-          err_msg = "Execution of '{0}' returned {1}".format(" ".join(cmd), rc)
-          raise ExecutionFailed(err_msg, rc, out)
+        Logger.info('Status check Elasticsearch slave node')
+        service_check(
+          cmd="service elasticsearch status",
+          user=params.elastic_status_check_user,
+          label="Elasticsearch Slave")
 
     def restart(self, env):
         import params
         env.set_params(params)
+        Logger.info('Restart Elasticsearch slave node')
         self.configure(env)
-        Logger.info('Restart Elasticsearch data node')
-        restart_cmd = "service elasticsearch restart"
-        Execute(restart_cmd)
+        Execute("service elasticsearch restart")
 
 
 if __name__ == "__main__":

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/params.py b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/params.py
index 4adcf43..0399c60 100755
--- a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/params.py
+++ b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/params.py
@@ -90,3 +90,16 @@ elastic_user_nofile_limit = config['configurations']['elastic-env']['elastic_use
 elastic_user_nproc_limit = config['configurations']['elastic-env']['elastic_user_nproc_limit']
 elastic_user_memlock_soft_limit = config['configurations']['elastic-env']['elastic_user_memlock_soft_limit']
 elastic_user_memlock_hard_limit = config['configurations']['elastic-env']['elastic_user_memlock_hard_limit']
+
+# the status check (service elasticsearch status) cannot be run by the 'elasticsearch'
+# user due to the default permissions that are set when the package is installed.  the
+# status check must be run as root
+elastic_status_check_user = 'root'
+
+# when using the RPM or Debian packages on systems that use systemd, system limits
+# must be specified via systemd.
+# see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/setting-system-settings.html#systemd
+systemd_parent_dir = '/etc/systemd/system/'
+systemd_elasticsearch_dir = systemd_parent_dir + 'elasticsearch.service.d/'
+systemd_override_file = systemd_elasticsearch_dir + 'override.conf'
+systemd_override_template = config['configurations']['elastic-systemd']['content']

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/service_check.py
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/service_check.py b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/service_check.py
index 4f8b1ab..3ac7c83 100755
--- a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/service_check.py
+++ b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/service_check.py
@@ -17,6 +17,8 @@ See the License for the specific language governing permissions and
 limitations under the License.
 
 """
+from __future__ import print_function
+
 import subprocess
 import sys
 import re
@@ -26,32 +28,33 @@ from resource_management.libraries.script import Script
 from resource_management.core.logger import Logger
 
 class ServiceCheck(Script):
+
     def service_check(self, env):
         import params
         env.set_params(params)
+        Logger.info("Running Elasticsearch service check")
 
-        doc = '{"name": "Ambari Smoke test"}'
-        index = "ambari_smoke_test"
+        port = self.get_port_from_range(params.http_port)
+        self.check_cluster_health(params.hostname, port)
+        self.index_document(params.hostname, port)
 
-        # http_port from ES config may be a port range.
-        es_http_port = re.search("^(\d+)", params.http_port).group(1)
-        host = params.hostname + ":" + es_http_port
-        Logger.info("Running Elastic search service check against " + host)
+        Logger.info("Elasticsearch service check successful")
+        exit(0)
 
-        # Make sure the service is actually up.  We can live without everything allocated.
-        # Need both the retry and ES timeout.  Can hit the URL before ES is ready at all and get no response, but can
-        # also hit ES before things are green.
-        Execute("curl -XGET 'http://%s/_cluster/health?wait_for_status=green&timeout=120s'" % host,
-                logoutput=True,
-                tries=6,
-                try_sleep=20
-                )
+    def index_document(self, host, port, doc='{"name": "Ambari Service Check"}', index="ambari_service_check"):
+        """
+        Tests the health of Elasticsearch by indexing a document.
 
-        # Put a document into a new index.
-        Execute("curl -XPUT '%s/%s/test/1' -d '%s'" % (host, index, doc), logoutput=True)
+        :param host: The name of a host running Elasticsearch.
+        :param port: The Elasticsearch HTTP port.
+        :param doc: The test document to put.
+        :param index: The name of the test index.
+        """
+        # put a document into a new index
+        Execute("curl -XPUT 'http://%s:%s/%s/test/1' -d '%s'" % (host, port, index, doc), logoutput=True)
 
-        # Retrieve the document.  Use subprocess because we actually need the results here.
-        cmd_retrieve = "curl -XGET '%s/%s/test/1'" % (host, index)
+        # retrieve the document...  use subprocess because we actually need the results here.
+        cmd_retrieve = "curl -XGET 'http://%s:%s/%s/test/1'" % (host, port, index)
         proc = subprocess.Popen(cmd_retrieve, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
         (stdout, stderr) = proc.communicate()
         response_retrieve = stdout
@@ -59,8 +62,8 @@ class ServiceCheck(Script):
         expected_retrieve = '{"_index":"%s","_type":"test","_id":"1","_version":1,"found":true,"_source":%s}' \
             % (index, doc)
 
-        # Delete the index
-        cmd_delete = "curl -XDELETE '%s/%s'" % (host, index)
+        # delete the test index
+        cmd_delete = "curl -XDELETE 'http://%s:%s/%s'" % (host, port, index)
         proc = subprocess.Popen(cmd_delete, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
         (stdout, stderr) = proc.communicate()
         response_delete = stdout
@@ -68,12 +71,43 @@ class ServiceCheck(Script):
         expected_delete = '{"acknowledged":true}'
 
         if (expected_retrieve == response_retrieve) and (expected_delete == response_delete):
-            Logger.info("Smoke test able to communicate with Elasticsearch")
+            Logger.info("Successfully indexed document in Elasticsearch")
         else:
-            Logger.info("Elasticsearch service unable to retrieve document.")
+            Logger.info("Unable to retrieve document from Elasticsearch")
             sys.exit(1)
 
-        exit(0)
+    def check_cluster_health(self, host, port, status="green", timeout="120s"):
+        """
+        Checks Elasticsearch cluster health.  Will wait for a given health
+        state to be reached.
+
+        :param host: The name of a host running Elasticsearch.
+        :param port: The Elasticsearch HTTP port.
+        :param status: The expected cluster health state.  By default, green.
+        :param timeout: How long to wait for the cluster.  By default, 120 seconds.
+        """
+        Logger.info("Checking cluster health")
+
+        cmd = "curl -sS -XGET 'http://{0}:{1}/_cluster/health?wait_for_status={2}&timeout={3}' | grep '\"status\":\"{2}\"'"
+        Execute(cmd.format(host, port, status, timeout), logoutput=True, tries=5, try_sleep=10)
+
+    def get_port_from_range(self, port_range, delimiter="-", default="9200"):
+        """
+        Elasticsearch is configured with a range of ports to bind to, such as
+        9200-9300.  This function identifies a single port within the given range.
+
+        :param port_range: A range of ports that Elasticsearch binds to.
+        :param delimiter: The port range delimiter, by default "-".
+        :param default: If no port can be identified in the port_range, the default is returned.
+        :return A single port within the given range.
+        """
+        port = default
+        if delimiter in port_range:
+            ports = port_range.split(delimiter)
+            if len(ports) > 0:
+                port = ports[0]
+
+        return port
 
 
 if __name__ == "__main__":

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/slave.py
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/slave.py b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/slave.py
deleted file mode 100755
index a19989e..0000000
--- a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/slave.py
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/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 resource_management.core.resources.system import Directory
-from resource_management.core.resources.system import File
-from resource_management.core.source import InlineTemplate
-from resource_management.core.source import Template
-from resource_management.core.resources import User
-from resource_management.core.logger import Logger
-
-def slave():
-    import params
-
-    Logger.info("Creating user: {0}:{1}".format(params.elastic_user, params.elastic_group))
-    User(params.elastic_user, action = "create", groups = params.elastic_group)
-
-    params.path_data = params.path_data.replace('"', '')
-    data_path = params.path_data.replace(' ', '').split(',')
-    data_path[:] = [x.replace('"', '') for x in data_path]
-    directories = [params.log_dir, params.pid_dir, params.conf_dir]
-    directories = directories + data_path
-
-    Logger.info("Creating directories: {0}".format(directories))
-    Directory(directories,
-              create_parents=True,
-              mode=0755,
-              owner=params.elastic_user,
-              group=params.elastic_group,
-              cd_access="a"
-              )
-
-    File("{0}/elastic-env.sh".format(params.conf_dir),
-         owner=params.elastic_user,
-         content=InlineTemplate(params.elastic_env_sh_template)
-         )
-
-    elastic_site = params.config['configurations']['elastic-site']
-    path = "{0}/elasticsearch.yml".format(params.conf_dir)
-    Logger.info("Creating ES slave configuration.")
-    File(path,
-         content=Template(
-             "elasticsearch.slave.yaml.j2",
-             configurations=elastic_site),
-         owner=params.elastic_user,
-         group=params.elastic_group
-         )
-
-    Logger.info("Slave sysconfig: /etc/sysconfig/elasticsearch")
-    File(format("/etc/sysconfig/elasticsearch"),
-         owner="root",
-         group="root",
-         content=InlineTemplate(params.sysconfig_template)
-         )
-
-    elastic_env = params.config['configurations']['elastic-env']
-    Logger.info("Slave PAM limits: {0}".format(params.limits_conf_file))
-    File(params.limits_conf_file,
-         content=Template(
-              'elasticsearch_limits.conf.j2',
-              configurations=elastic_env),
-         owner="root",
-         group="root"
-         )

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/status_params.py
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/status_params.py b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/status_params.py
index 9cfb5cf..0629735 100755
--- a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/status_params.py
+++ b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/ELASTICSEARCH/5.6.2/package/scripts/status_params.py
@@ -24,3 +24,4 @@ config = Script.get_config()
 
 elastic_pid_dir = config['configurations']['elastic-env']['elastic_pid_dir']
 elastic_pid_file = format("{elastic_pid_dir}/elasticsearch.pid")
+elastic_user = config['configurations']['elastic-env']['elastic_user']

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/KIBANA/5.6.2/metainfo.xml
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/KIBANA/5.6.2/metainfo.xml b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/KIBANA/5.6.2/metainfo.xml
index 034f71c..06b61a1 100755
--- a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/KIBANA/5.6.2/metainfo.xml
+++ b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/KIBANA/5.6.2/metainfo.xml
@@ -48,7 +48,7 @@
             </components>
             <osSpecifics>
                 <osSpecific>
-                    <osFamily>any</osFamily>
+                    <osFamily>redhat6</osFamily>
                     <packages>
                         <package>
                             <name>python-elasticsearch</name>
@@ -58,6 +58,25 @@
                         </package>
                     </packages>
                 </osSpecific>
+                <osSpecific>
+                    <osFamily>redhat7</osFamily>
+                    <packages>
+                        <package>
+                            <name>python-elasticsearch</name>
+                        </package>
+                        <package>
+                            <name>kibana-5.6.2</name>
+                        </package>
+                    </packages>
+                </osSpecific>
+                <osSpecific>
+                    <osFamily>ubuntu14</osFamily>
+                    <packages>
+                        <package>
+                            <name>kibana=5.6.2</name>
+                        </package>
+                    </packages>
+                </osSpecific>
             </osSpecifics>
             <configuration-dependencies>
                 <config-type>kibana-env</config-type>

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/KIBANA/5.6.2/package/scripts/common.py
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/KIBANA/5.6.2/package/scripts/common.py b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/KIBANA/5.6.2/package/scripts/common.py
new file mode 100644
index 0000000..37100cd
--- /dev/null
+++ b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/KIBANA/5.6.2/package/scripts/common.py
@@ -0,0 +1,56 @@
+"""
+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.libraries.functions.get_user_call_output import get_user_call_output
+from resource_management.core.exceptions import ExecutionFailed
+from resource_management.core.exceptions import ComponentIsNotRunning
+
+def service_check(cmd, user, label):
+    """
+    Executes a service check command that adheres to LSB-compliant
+    return codes.  The return codes are interpreted as defined
+    by the LSB.
+
+    See http://refspecs.linuxbase.org/LSB_3.0.0/LSB-PDA/LSB-PDA/iniscrptact.html
+    for more information.
+
+    :param cmd: The service check command to execute.
+    :param label: The name of the service.
+    """
+    Logger.info("Performing service check; cmd={0}, user={1}, label={2}".format(cmd, user, label))
+    rc, out, err = get_user_call_output(cmd, user, is_checked_call=False)
+
+    if len(err) > 0:
+      Logger.error(err)
+
+    if rc in [1, 2, 3]:
+      # if return code in [1, 2, 3], then 'program is not running' or 'program is dead'
+      Logger.info("{0} is not running".format(label))
+      raise ComponentIsNotRunning()
+
+    elif rc == 0:
+      # if return code = 0, then 'program is running or service is OK'
+      Logger.info("{0} is running".format(label))
+
+    else:
+      # else service state is unknown
+      err_msg = "{0} service check failed; cmd '{1}' returned {2}".format(label, cmd, rc)
+      Logger.error(err_msg)
+      raise ExecutionFailed(err_msg, rc, out, err)

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/KIBANA/5.6.2/package/scripts/kibana_master.py
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/KIBANA/5.6.2/package/scripts/kibana_master.py b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/KIBANA/5.6.2/package/scripts/kibana_master.py
index 861e19a..a15f709 100755
--- a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/KIBANA/5.6.2/package/scripts/kibana_master.py
+++ b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/KIBANA/5.6.2/package/scripts/kibana_master.py
@@ -14,18 +14,14 @@ 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.
-
-kibana_master
-
 """
 
 import errno
 import os
 
+from ambari_commons.os_check import OSCheck
 from ambari_commons.os_family_impl import OsFamilyFuncImpl, OsFamilyImpl
-from resource_management.core import shell
-from resource_management.core.exceptions import ExecutionFailed
-from resource_management.core.exceptions import ComponentIsNotRunning
+
 from resource_management.core.logger import Logger
 from resource_management.core.resources.system import Directory
 from resource_management.core.resources.system import Execute
@@ -34,23 +30,23 @@ from resource_management.core.source import InlineTemplate
 from resource_management.libraries.functions.format import format as ambari_format
 from resource_management.libraries.script import Script
 
+from common import service_check
 
 class Kibana(Script):
+
     def install(self, env):
         import params
         env.set_params(params)
-        Logger.info("Install Kibana Master")
+        Logger.info("Installing Kibana")
         self.install_packages(env)
 
     def configure(self, env, upgrade_type=None, config_dir=None):
         import params
         env.set_params(params)
-
-        Logger.info("Configure Kibana for Metron")
+        Logger.info("Configuring Kibana")
 
         directories = [params.log_dir, params.pid_dir, params.conf_dir]
         Directory(directories,
-                  create_parents=True,
                   mode=0755,
                   owner=params.kibana_user,
                   group=params.kibana_user
@@ -64,58 +60,28 @@ class Kibana(Script):
     def stop(self, env, upgrade_type=None):
         import params
         env.set_params(params)
-
-        Logger.info("Stop Kibana Master")
-
+        Logger.info("Stopping Kibana")
         Execute("service kibana stop")
 
     def start(self, env, upgrade_type=None):
         import params
         env.set_params(params)
-
         self.configure(env)
-
-        Logger.info("Start the Master")
-
-
+        Logger.info("Starting Kibana")
         Execute("service kibana start")
 
     def restart(self, env):
         import params
         env.set_params(params)
-
         self.configure(env)
-
-        Logger.info("Restarting the Master")
-
+        Logger.info("Restarting Kibana")
         Execute("service kibana restart")
 
     def status(self, env):
         import params
         env.set_params(params)
-
-        Logger.info("Status of the Master")
-
-        # return codes defined by LSB
-        # http://refspecs.linuxbase.org/LSB_3.0.0/LSB-PDA/LSB-PDA/iniscrptact.html
-        cmd = ('service', 'kibana', 'status')
-        rc, out = shell.call(cmd, sudo=True, quiet=False)
-
-        if rc in [1, 2, 3]:
-          # if return code = 1, 2, or 3, then 'program is not running' or 'dead'
-          # Ambari's resource_management/libraries/script/script.py handles
-          # this specific exception as OK
-          Logger.info("Kibana is not running")
-          raise ComponentIsNotRunning()
-
-        elif rc == 0:
-          # if return code = 0, then 'program is running or service is OK'
-          Logger.info("Kibana is running")
-
-        else:
-          # else, program is dead or service state is unknown
-          err_msg = "Execution of '{0}' returned {1}".format(" ".join(cmd), rc)
-          raise ExecutionFailed(err_msg, rc, out)
+        Logger.info('Status check Kibana')
+        service_check("service kibana status", user=params.kibana_user, label="Kibana")
 
     @OsFamilyFuncImpl(os_family=OsFamilyImpl.DEFAULT)
     def load_template(self, env):

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/METRON/CURRENT/package/scripts/indexing_master.py
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/METRON/CURRENT/package/scripts/indexing_master.py b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/METRON/CURRENT/package/scripts/indexing_master.py
index 4b11456..18d5224 100755
--- a/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/METRON/CURRENT/package/scripts/indexing_master.py
+++ b/metron-deployment/packaging/ambari/metron-mpack/src/main/resources/common-services/METRON/CURRENT/package/scripts/indexing_master.py
@@ -95,9 +95,8 @@ class Indexing(Script):
 
         except Exception as e:
             msg = "WARNING: Elasticsearch index templates could not be installed.  " \
-                  "Is Elasticsearch running?  error={0}"
+                  "Is Elasticsearch running?  Will reattempt install on next start.  error={0}"
             Logger.warning(msg.format(e))
-            raise
 
         commands.start_indexing_topology(env)
 

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/docker/deb-docker/build.sh
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/docker/deb-docker/build.sh b/metron-deployment/packaging/docker/deb-docker/build.sh
index 0a79841..1fded4b 100755
--- a/metron-deployment/packaging/docker/deb-docker/build.sh
+++ b/metron-deployment/packaging/docker/deb-docker/build.sh
@@ -20,14 +20,11 @@ export FULL_VERSION=$1
 export VERSION=$(echo ${FULL_VERSION} | tr -d '"'"'[:alpha:]'"'"')
 export DISTRIBUTION="trusty"
 
-echo "FULL_VERSION: ${FULL_VERSION}"
-echo "VERSION: ${VERSION}"
-
 INSTALL_PREFIX="/usr/metron"
 METRON_HOME="${INSTALL_PREFIX}/${FULL_VERSION}"
 HOMEDIR="/root"
 WORKDIR="${HOMEDIR}/target"
-CONFIGDIR="${HOMEDIR}/debian/"
+CONFIGDIR="${HOMEDIR}/debian"
 DATE=`date '+%Y%m%d%H%M'`
 PREPACKAGEDIR="${HOMEDIR}/prepackage"
 
@@ -39,9 +36,26 @@ cd "${WORKDIR}"
 for TARBALL in metron*.tar.gz; do
 
     export PACKAGE=`echo ${TARBALL} | awk -F"-${FULL_VERSION}-" '{print $1}'`
+    if [ "${PACKAGE}" = "metron-pcap-backend" ]; then
+        # work around for inconsistent naming of 'metron-pcap-backend' ...
+        #
+        #  * the tarball is named 'metron-pcap-backend'
+        #  * but the RPM is created as 'metron-pcap'
+        #  * the mpack also expects the package to be named 'metron-pcap'
+        #
+        # ... rather than use the tarball name here, rewrite the name to be
+        # consistent with the RPMs and MPack
+        export PACKAGE="metron-pcap"
+    fi
     export PACKAGE_WORKDIR="${WORKDIR}/${PACKAGE}_${FULL_VERSION}"
     echo "Building package; name=${PACKAGE}, tarball=${TARBALL}"
 
+    # if the tarball does not exist, fail fast
+    if [ ! -f "${TARBALL}" ]; then
+        echo "ERROR: Missing ${TARBALL}"
+        exit 1
+    fi
+
     # extract the package contents
     mkdir -p ${PACKAGE_WORKDIR}/${METRON_HOME}
     tar xf ${TARBALL} -C ${PACKAGE_WORKDIR}/${METRON_HOME}
@@ -51,17 +65,36 @@ for TARBALL in metron*.tar.gz; do
     PACKAGE_DEBIAN_DIR="${PACKAGE_WORKDIR}/DEBIAN"
     mkdir ${PACKAGE_DEBIAN_DIR}
 
-    # create the configuration files
-    envsubst < ${CONFIGDIR}/control > ${PACKAGE_DEBIAN_DIR}/control
-    envsubst < ${CONFIGDIR}/changelog > ${PACKAGE_DEBIAN_DIR}/changelog
-    envsubst < ${CONFIGDIR}/copyright > ${PACKAGE_DEBIAN_DIR}/copyright
+    # all packages get the control files contained in `debian/metron`
+    for CFILE in ${CONFIGDIR}/metron/*; do
+        [ -e "$CFILE" ] || continue
+        CFILENAME=`basename "${CFILE}"`
+        DEST="${PACKAGE_DEBIAN_DIR}/${CFILENAME}"
+
+        # copy over the control file (allowing for variable substitution)
+        envsubst < ${CFILE} > ${DEST}
+
+        # strip comments from the control file
+        sed -i '/#[^!]*$/d' ${DEST}
+    done
+
+    # a package *may* have control files specific to it in `debian/$PACKAGE`
+    for CFILE in ${CONFIGDIR}/${PACKAGE}/*; do
+        [ -e "$CFILE" ] || continue
+        CFILENAME=`basename "${CFILE}"`
+        DEST="${PACKAGE_DEBIAN_DIR}/${CFILENAME}"
+
+        # copy over the control file (allowing for variable substitution)
+        envsubst < ${CFILE} > ${DEST}
+
+        # strip comments from the control file (don't delete shebangs!)
+        sed -i '/#[^!]*$/d' ${DEST}
 
-    # strip comments from the config files
-    sed -i 's/#.*$//g' ${PACKAGE_DEBIAN_DIR}/control
-    sed -i 's/#.*$//g' ${PACKAGE_DEBIAN_DIR}/changelog
-    sed -i 's/#.*$//g' ${PACKAGE_DEBIAN_DIR}/copyright
+        # permissions must be 0755 for maintain scripts like preinst and postinst
+        chmod 0755 ${DEST}
+    done
 
-    # execute the prepackage script, if one exists
+    # execute the prepackage script, if one exists for the package
     if [ -f "${PREPACKAGEDIR}/${PACKAGE}" ]; then
         source ${PREPACKAGEDIR}/${PACKAGE}
     fi

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/docker/deb-docker/debian/changelog
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/docker/deb-docker/debian/changelog b/metron-deployment/packaging/docker/deb-docker/debian/changelog
deleted file mode 100644
index 8b271bf..0000000
--- a/metron-deployment/packaging/docker/deb-docker/debian/changelog
+++ /dev/null
@@ -1,22 +0,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.
-#
-
-$PACKAGE ($FULL_VERSION) $DISTRIBUTION; urgency=medium
-
-  * Initial release. (Closes: METRON-1351)
-
- -- Apache Metron <de...@metron.apache.org>  Wed, 13 Dec 2017 21:19:45 +0000

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/docker/deb-docker/debian/control
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/docker/deb-docker/debian/control b/metron-deployment/packaging/docker/deb-docker/debian/control
deleted file mode 100644
index febd3a9..0000000
--- a/metron-deployment/packaging/docker/deb-docker/debian/control
+++ /dev/null
@@ -1,28 +0,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.
-#
-
-Source: metron
-Section: misc
-Priority: extra
-Maintainer: Apache Metron <de...@metron.apache.org>
-Homepage: https://metron.apache.org/
-Package: $PACKAGE
-Architecture: all
-Version: $FULL_VERSION
-Depends:
-Description: Apache Metron
-  Apache Metron provides a scalable advanced security analytics framework.

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/docker/deb-docker/debian/copyright
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/docker/deb-docker/debian/copyright b/metron-deployment/packaging/docker/deb-docker/debian/copyright
deleted file mode 100644
index d02dfb0..0000000
--- a/metron-deployment/packaging/docker/deb-docker/debian/copyright
+++ /dev/null
@@ -1,35 +0,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.
-#
-
-Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
-Upstream-Name: $PACKAGE
-Upstream-Contact: Apache Metron <de...@metron.apache.org>
-
-Files: *
-License: ASL-2
-Copyright:
-Apache Metron
-Copyright 2015-2016 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-
-This product includes software developed by Cisco Systems (http://www.cisco.com)
-Copyright (c) 2014 Cisco Systems.
-
-This product includes software developed by Chef Software (https://www.chef.io)
-Copyright (c) 2012-2015, Chef Software, Inc.

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/docker/deb-docker/debian/metron-alerts/postinst
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/docker/deb-docker/debian/metron-alerts/postinst b/metron-deployment/packaging/docker/deb-docker/debian/metron-alerts/postinst
new file mode 100644
index 0000000..6f56bd7
--- /dev/null
+++ b/metron-deployment/packaging/docker/deb-docker/debian/metron-alerts/postinst
@@ -0,0 +1,26 @@
+#!/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.
+#
+
+#
+# this script is executed AFTER installation of the 'metron-alerts' package
+# comments are stripped from this file before packaging
+# environment variable substitution is performed on this file before packaging
+#
+
+# install the service script
+cp -f /usr/metron/${FULL_VERSION}/bin/metron-alerts-ui /etc/init.d/

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/docker/deb-docker/debian/metron-alerts/postrm
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/docker/deb-docker/debian/metron-alerts/postrm b/metron-deployment/packaging/docker/deb-docker/debian/metron-alerts/postrm
new file mode 100644
index 0000000..0ea1905
--- /dev/null
+++ b/metron-deployment/packaging/docker/deb-docker/debian/metron-alerts/postrm
@@ -0,0 +1,25 @@
+#!/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.
+#
+
+#
+# this script is executed AFTER removal of the 'metron-alerts' package
+# comments are stripped from this file before packaging
+# environment variable substitution is performed on this file before packaging
+#
+
+rm -f /etc/init.d/metron-alerts-ui

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/docker/deb-docker/debian/metron-alerts/preinst
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/docker/deb-docker/debian/metron-alerts/preinst b/metron-deployment/packaging/docker/deb-docker/debian/metron-alerts/preinst
new file mode 100644
index 0000000..33c7262
--- /dev/null
+++ b/metron-deployment/packaging/docker/deb-docker/debian/metron-alerts/preinst
@@ -0,0 +1,29 @@
+#!/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.
+#
+
+#
+# this script is executed BEFORE installation of the 'metron-alerts' package.
+# comments are stripped from this file before packaging
+# environment variable substitution is performed on this file before packaging
+#
+if [ -f "/etc/init.d/metron-alerts-ui"]; then
+    # if service already exists, stop it before upgrading
+    /etc/init.d/metron-alerts-ui stop
+fi
+
+exit 0

http://git-wip-us.apache.org/repos/asf/metron/blob/6f267991/metron-deployment/packaging/docker/deb-docker/debian/metron-alerts/prerm
----------------------------------------------------------------------
diff --git a/metron-deployment/packaging/docker/deb-docker/debian/metron-alerts/prerm b/metron-deployment/packaging/docker/deb-docker/debian/metron-alerts/prerm
new file mode 100644
index 0000000..403196b
--- /dev/null
+++ b/metron-deployment/packaging/docker/deb-docker/debian/metron-alerts/prerm
@@ -0,0 +1,30 @@
+#!/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.
+#
+
+#
+# this script is executed BEFORE removal of the 'metron-alerts' package.
+# comments are stripped from this file before packaging
+# environment variable substitution is performed on this file before packaging
+#
+
+# if service exists, stop it
+if [ -f "/etc/init.d/metron-alerts-ui"]; then
+    /etc/init.d/metron-alerts-ui stop
+fi
+
+exit 0