Merge tag '2016.12.1' into debian/unstable

2016.12.1
diff --git a/FORMULA b/FORMULA
new file mode 100644
index 0000000..77328cf
--- /dev/null
+++ b/FORMULA
@@ -0,0 +1,8 @@
+name: horizon
+os: Debian, RedHat
+os_family: Debian, RedHat
+version: 201606
+release: 1
+summary: Formula for installing and configuring horizon
+description: Formula for installing and configuring horizon
+top_level_dir: horizon
diff --git a/README.rst b/README.rst
index 27511bd..a486264 100644
--- a/README.rst
+++ b/README.rst
@@ -11,25 +11,14 @@
 Packaged version of horizon
 ---------------------------
 
-One horizon on server
-
-Simplest horizon setup with managed cloud-archive repo on ubuntu 12.04
+Simplest horizon setup
 
 .. code-block:: yaml
 
-    linux:
-      system:
-        name: horizon
-        repo:
-         - cloudarchive-havana:
-            enabled: true
-            source: 'deb http://ubuntu-cloud.archive.canonical.com/ubuntu precise-updates/havana main'
-            pgpcheck: 0
     horizon:
       server:
-        manage_repo: true
         enabled: true
-        secret_key: MEGASECRET
+        secret_key: secret
         host:
           name: cloud.lab.cz
         cache:
@@ -121,21 +110,13 @@
         sensu_api:
           host: localhost
           port: 4567
-        plugins:
-        - name: monitoring
-          app: horizon_monitoring
-          source:
-            type: git
-            address: git@repo1.robotice.cz:django/horizon-monitoring.git
-            rev: develop
-        - name: api-mask
-          app: api_mask
-          mask_url: 'custom-url.cz'
-          mask_protocol: 'http'
-          source:
-            type: git
-            address: git@repo1.robotice.cz:django/horizon-api-mask.git
-            rev: develop
+        plugin:
+          monitoring:
+            app: horizon_monitoring
+            source:
+              type: git
+              address: git@repo1.robotice.cz:django/horizon-monitoring.git
+              rev: develop
 
 Sensu multi API
 
@@ -153,6 +134,24 @@
             host: anotherhost
             port: 4567
 
+Horizon setup with jenkins plugin
+
+.. code-block:: yaml
+
+    horizon:
+      server:
+        enabled: true
+        version: juno
+        jenkins_api:
+          url: https://localhost:8080
+          user: admin
+          password: pwd
+        plugin:
+          jenkins:
+            app: horizon_jenkins
+            source:
+              type: pkg
+
 Horizon setup with billometer plugin
 
 .. code-block:: yaml
@@ -165,13 +164,13 @@
           host: localhost
           port: 9753
           api_version: 1
-        plugins:
-        - name: billing
-          app: horizon_billing
-          source:
-            type: git
-            address: git@repo1.robotice.cz:django/horizon-billing.git
-            rev: develop
+        plugin:
+          billing:
+            app: horizon_billing
+            source:
+              type: git
+              address: git@repo1.robotice.cz:django/horizon-billing.git
+              rev: develop
 
 Horizon setup with contrail plugin
 
@@ -181,14 +180,14 @@
       server:
         enabled: true
         version: icehouse
-        plugins:
-        - name: contrail
-          app: contrail_openstack_dashboard
-          override: true
-          source:
-            type: git
-            address: git@repo1.robotice.cz:django/horizon-contrail.git
-            rev: develop
+        plugin:
+          contrail:
+            app: contrail_openstack_dashboard
+            override: true
+            source:
+              type: git
+              address: git@repo1.robotice.cz:django/horizon-contrail.git
+              rev: develop
 
 Horizon setup with sentry log handler
 
@@ -338,7 +337,7 @@
         enabled: true
         app:
           openstack_dashboard_overrride:
-            secret_key: MEGASECRET1
+            secret_key: password
             dashboards:
               settings:
                 enabled: true
@@ -358,12 +357,3 @@
 
 * https://github.com/openstack/horizon
 * http://dijks.wordpress.com/2012/07/06/how-to-change-screen-resolution-of-novnc-client-in-openstack-essex-dashboard-nova-horizon/
-
-
-Things to improve
-=================
-
-* ALLOWED_HOSTS - do not use * - introduce parameters
-* CACHES - configure caching engine - is it not allowed by default?
-* SESSION_ENGINE - change it from signed cookie to something else
-* policy files - look into these files and think of further configuration/parametrisation
diff --git a/other-requirements.txt b/bindep.txt
similarity index 100%
rename from other-requirements.txt
rename to bindep.txt
diff --git a/horizon/files/enabled/jenkins.py b/horizon/files/enabled/jenkins.py
new file mode 100644
index 0000000..7b5247b
--- /dev/null
+++ b/horizon/files/enabled/jenkins.py
@@ -0,0 +1,10 @@
+
+ENABLED = True
+
+DASHBOARD = 'jenkins'
+# If set to True, this dashboard will be set as the default dashboard.
+DEFAULT = False
+# A dictionary of exception classes to be added to HORIZON['exceptions'].
+ADD_EXCEPTIONS = {}
+# A list of applications to be added to INSTALLED_APPS.
+ADD_INSTALLED_APPS = ['horizon_jenkins']
\ No newline at end of file
diff --git a/horizon/files/entrypoint.sh b/horizon/files/entrypoint.sh
new file mode 100644
index 0000000..9bf2da5
--- /dev/null
+++ b/horizon/files/entrypoint.sh
@@ -0,0 +1,22 @@
+{%- from "horizon/map.jinja" import server with context -%}
+#!/bin/bash -e
+
+cat /srv/salt/pillar/horizon-server.sls | envsubst > /tmp/horizon-server.sls
+mv /tmp/horizon-server.sls /srv/salt/pillar/horizon-server.sls
+
+salt-call --local --retcode-passthrough state.highstate
+
+service {{ server.service }} stop || true
+
+export APACHE_RUN_USER=horizon
+export APACHE_RUN_GROUP=horizon
+export APACHE_PID_FILE=/var/run/apache2/apache2.pid
+export APACHE_RUN_DIR=/var/run/apache2
+export APACHE_LOCK_DIR=/var/lock/apache2
+export APACHE_LOG_DIR=/var/log/apache2
+
+apachectl -DFOREGROUND
+
+{#-
+vim: syntax=jinja
+-#}
diff --git a/horizon/files/horizon_settings/_local_settings.py b/horizon/files/horizon_settings/_local_settings.py
index 8148ddc..00df73e 100644
--- a/horizon/files/horizon_settings/_local_settings.py
+++ b/horizon/files/horizon_settings/_local_settings.py
@@ -76,6 +76,12 @@
 OPENSTACK_CONTROL_NODES = {{ app.control_nodes|python }}
 {%- endif %}
 
+{%- if app.jenkins_api is defined %}
+HORIZON_JENKINS_URL = "{{ app.jenkins_api.url }}"
+HORIZON_JENKINS_USERNAME = "{{ app.jenkins_api.user }}"
+HORIZON_JENKINS_PASSWORD = "{{ app.jenkins_api.password }}"
+{%- endif %}
+
 {%- if app.sensu_api is defined %}
 {%- if app.sensu_api.host is defined %}
 SENSU_HOST = '{{ app.sensu_api.host }}'
diff --git a/horizon/files/local_settings/kilo_settings.py b/horizon/files/local_settings/kilo_settings.py
index 3c59278..0f14217 100644
--- a/horizon/files/local_settings/kilo_settings.py
+++ b/horizon/files/local_settings/kilo_settings.py
@@ -31,7 +31,7 @@
 
 {%- if app.theme is defined %}
 CUSTOM_THEME_PATH = 'static/themes/{{ app.theme }}'
-{%- elif app.plugin.horizon_theme.theme_name is defined %}
+{%- elif app.plugin is defined and app.plugin.horizon_theme.theme_name is defined %}
 CUSTOM_THEME_PATH = 'static/themes/{{ app.plugin.horizon_theme.theme_name }}'
 {%- endif %}
 
diff --git a/horizon/files/local_settings/liberty_settings.py b/horizon/files/local_settings/liberty_settings.py
index 47e3587..22e3a4d 100644
--- a/horizon/files/local_settings/liberty_settings.py
+++ b/horizon/files/local_settings/liberty_settings.py
@@ -28,7 +28,7 @@
     'js_spec_files': [],
     'password_autocomplete': 'on'
 }
-{%- if app.theme is defined or app.plugin.horizon_theme is defined %}
+{%- if app.theme is defined or (app.plugin is defined and app.plugin.horizon_theme is defined) %}
 {%- if app.theme is defined %}
 CUSTOM_THEME_PATH = 'themes/{{ app.theme }}'
 {%- elif app.plugin.horizon_theme.theme_name is defined %}
diff --git a/horizon/files/local_settings/mitaka_settings.py b/horizon/files/local_settings/mitaka_settings.py
index 47e3587..22e3a4d 100644
--- a/horizon/files/local_settings/mitaka_settings.py
+++ b/horizon/files/local_settings/mitaka_settings.py
@@ -28,7 +28,7 @@
     'js_spec_files': [],
     'password_autocomplete': 'on'
 }
-{%- if app.theme is defined or app.plugin.horizon_theme is defined %}
+{%- if app.theme is defined or (app.plugin is defined and app.plugin.horizon_theme is defined) %}
 {%- if app.theme is defined %}
 CUSTOM_THEME_PATH = 'themes/{{ app.theme }}'
 {%- elif app.plugin.horizon_theme.theme_name is defined %}
diff --git a/horizon/files/openstack-dashboard.conf.Debian b/horizon/files/openstack-dashboard.conf.Debian
index 40942a2..f903c08 100644
--- a/horizon/files/openstack-dashboard.conf.Debian
+++ b/horizon/files/openstack-dashboard.conf.Debian
@@ -1,27 +1,36 @@
 {%- from "horizon/map.jinja" import server with context %}
 
-WSGIScriptAlias / /usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi
-WSGIDaemonProcess horizon user=horizon group=horizon processes={{ server.wsgi.processes }} threads={{ server.wsgi.threads }}
-WSGIProcessGroup horizon
+<VirtualHost {{ server.get('bind', {}).get('address', '0.0.0.0') }}:{{ server.get('bind', {}).get('port', 80) }}>
+  ServerName {{ server.get('host', {}).get('name', 'openstack-dashboard') }}
 
-Alias /static /usr/share/openstack-dashboard/static
+  WSGIScriptAlias / /usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi
+  WSGIDaemonProcess horizon user=horizon group=horizon processes={{ server.wsgi.processes }} threads={{ server.wsgi.threads }}
+  WSGIProcessGroup horizon
 
-<Directory /usr/share/openstack-dashboard/openstack_dashboard/wsgi>
-  Order allow,deny
-  Allow from all
-</Directory>
+  Alias /static /usr/share/openstack-dashboard/static
 
-<Directory /usr/share/openstack-dashboard/static>
-  <IfModule mod_expires.c>
-    ExpiresActive On
-    ExpiresDefault "access 6 month"
-  </IfModule>
-  <IfModule mod_deflate.c>
-    SetOutputFilter DEFLATE
-  </IfModule>
+  <Directory /usr/share/openstack-dashboard/openstack_dashboard/wsgi>
+    Order allow,deny
+    Allow from all
+  </Directory>
 
-  Require all granted
-</Directory>
+  <Directory /usr/share/openstack-dashboard/static>
+    <IfModule mod_expires.c>
+      ExpiresActive On
+      ExpiresDefault "access 6 month"
+    </IfModule>
+    <IfModule mod_deflate.c>
+      SetOutputFilter DEFLATE
+    </IfModule>
+
+    Require all granted
+  </Directory>
+  ServerSignature Off
+  LogFormat "{{ server.apache_log_format }}" horizon
+  ErrorLog "{{ server.apache_log_dir }}/{{ server.apache_log_filename }}_error.log"
+  CustomLog "{{ server.apache_log_dir }}/{{ server.apache_log_filename }}_access.log" horizon
+
+</VirtualHost>
 
 {% if server.get('ssl', {}).get('enabled', False) %}
 
@@ -51,6 +60,11 @@
     Order allow,deny
     Allow from all
   </Directory>
+
+  ServerSignature Off
+  LogFormat "{{ server.apache_log_format }}" horizon
+  ErrorLog "{{ server.apache_log_dir }}/{{ server.apache_log_filename }}_error_ssl.log"
+  CustomLog "{{ server.apache_log_dir }}/{{ server.apache_log_filename }}_access_ssl.log" horizon
 </VirtualHost>
 
-{% endif %}
\ No newline at end of file
+{% endif %}
diff --git a/horizon/files/requirements/liberty_contrail.txt b/horizon/files/requirements/liberty_contrail.txt
index 76e111d..c273fed 100644
--- a/horizon/files/requirements/liberty_contrail.txt
+++ b/horizon/files/requirements/liberty_contrail.txt
@@ -23,7 +23,7 @@
 kombu>=3.0.7
 netaddr!=0.7.16,>=0.7.12
 oslo.concurrency>=2.3.0 # Apache-2.0
-oslo.config>=2.3.0 # Apache-2.0
+oslo.config==1.9.0 # Apache-2.0
 oslo.i18n>=1.5.0 # Apache-2.0
 oslo.policy>=0.5.0 # Apache-2.0
 oslo.serialization>=1.4.0 # Apache-2.0
@@ -67,6 +67,7 @@
 XStatic-smart-table>=1.4.5.3 # MIT License
 XStatic-Spin>=1.2.5.2 # MIT License
 XStatic-term.js>=0.0.4 # MIT License
+XStatic-QUnit>=1.14 # MIT License
 
 horizon-contrib>=2015.10.0
 
diff --git a/horizon/files/requirements/liberty_vanilla.txt b/horizon/files/requirements/liberty_vanilla.txt
index 190e111..e8321f4 100644
--- a/horizon/files/requirements/liberty_vanilla.txt
+++ b/horizon/files/requirements/liberty_vanilla.txt
@@ -23,7 +23,7 @@
 kombu>=3.0.7
 netaddr!=0.7.16,>=0.7.12
 oslo.concurrency>=2.3.0 # Apache-2.0
-oslo.config>=2.3.0 # Apache-2.0
+oslo.config==1.9.0 # Apache-2.0
 oslo.i18n>=1.5.0 # Apache-2.0
 oslo.policy>=0.5.0 # Apache-2.0
 oslo.serialization>=1.4.0 # Apache-2.0
@@ -67,6 +67,7 @@
 XStatic-smart-table>=1.4.5.3 # MIT License
 XStatic-Spin>=1.2.5.2 # MIT License
 XStatic-term.js>=0.0.4 # MIT License
+XStatic-QUnit>=1.14 # MIT License
 
 horizon-contrib>=2015.7.6
 python-memcached
diff --git a/horizon/files/requirements/mitaka_contrail.txt b/horizon/files/requirements/mitaka_contrail.txt
index 57e9a31..38b800e 100644
--- a/horizon/files/requirements/mitaka_contrail.txt
+++ b/horizon/files/requirements/mitaka_contrail.txt
@@ -7,36 +7,36 @@
 # be installed in a specific order.
 #
 # PBR should always appear first
-pbr>=1.6
+pbr>=1.6 # Apache-2.0
 # Horizon Core Requirements
-Babel>=1.3
-Django<1.9,>=1.8
+Babel!=2.3.0,!=2.3.1,!=2.3.2,!=2.3.3,>=1.3 # BSD
+Django<1.9,>=1.8 # BSD
 Pint>=0.5 # BSD
-django-babel>=0.4.0
-django-compressor>=1.4
-django-openstack-auth>=2.0.0
+django-babel>=0.4.0 # BSD
+django-compressor>=2.0 # MIT
+django-openstack-auth>=2.0.0 # Apache-2.0
 django-pyscss>=2.0.2 # BSD License (2 clause)
-httplib2>=0.7.5
-iso8601>=0.1.9
-netaddr!=0.7.16,>=0.7.12
-oslo.concurrency>=2.3.0 # Apache-2.0
-oslo.config>=3.2.0 # Apache-2.0
-oslo.i18n>=1.5.0 # Apache-2.0
+httplib2>=0.7.5 # MIT
+iso8601>=0.1.9 # MIT
+netaddr!=0.7.16,>=0.7.12 # BSD
+oslo.concurrency>=3.7.1 # Apache-2.0
+oslo.config>=3.7.0 # Apache-2.0
+oslo.i18n>=2.1.0 # Apache-2.0
 oslo.policy>=0.5.0 # Apache-2.0
 oslo.serialization>=1.10.0 # Apache-2.0
-oslo.utils>=3.2.0 # Apache-2.0
+oslo.utils>=3.5.0 # Apache-2.0
 pyScss>=1.3.4 # MIT License
-python-ceilometerclient>=2.0.0
-python-cinderclient>=1.3.1
-python-glanceclient>=1.2.0
-python-heatclient>=0.6.0
-python-keystoneclient!=1.8.0,>=1.6.0
-python-neutronclient>=2.6.0
-python-novaclient!=2.33.0,>=2.29.0
-python-swiftclient>=2.2.0
-pytz>=2013.6
-PyYAML>=3.1.0
-six>=1.9.0
+python-ceilometerclient>=2.2.1 # Apache-2.0
+python-cinderclient>=1.3.1 # Apache-2.0
+python-glanceclient>=2.0.0 # Apache-2.0
+python-heatclient>=0.6.0 # Apache-2.0
+python-keystoneclient!=1.8.0,!=2.1.0,<3.0.0,>=1.6.0 # Apache-2.0
+python-neutronclient!=4.1.0,>=2.6.0 # Apache-2.0
+python-novaclient!=2.33.0,>=2.29.0 # Apache-2.0
+python-swiftclient>=2.2.0 # Apache-2.0
+pytz>=2013.6 # MIT
+PyYAML>=3.1.0 # MIT
+six>=1.9.0 # MIT
 XStatic>=1.0.0 # MIT License
 XStatic-Angular>=1.3.7 # MIT License
 XStatic-Angular-Bootstrap>=0.11.0.2 # MIT License
@@ -55,7 +55,6 @@
 XStatic-JQuery.TableSorter>=2.14.5.1 # MIT License
 XStatic-jquery-ui>=1.10.1 # MIT License
 XStatic-JSEncrypt>=2.0.0.2 # MIT License
-XStatic-Magic-Search>=0.2.5.1 # Apache 2.0 License
 XStatic-mdi==1.1.70.1 # SIL OPEN FONT LICENSE Version 1.1
 XStatic-Rickshaw>=1.5.0 # BSD License (prior)
 XStatic-roboto-fontface>=0.4.3.2 # Apache 2.0 License
diff --git a/horizon/files/requirements/mitaka_vanilla.txt b/horizon/files/requirements/mitaka_vanilla.txt
index 696615b..87fd37f 100644
--- a/horizon/files/requirements/mitaka_vanilla.txt
+++ b/horizon/files/requirements/mitaka_vanilla.txt
@@ -7,36 +7,36 @@
 # be installed in a specific order.
 #
 # PBR should always appear first
-pbr>=1.6
+pbr>=1.6 # Apache-2.0
 # Horizon Core Requirements
-Babel>=1.3
-Django<1.9,>=1.8
+Babel!=2.3.0,!=2.3.1,!=2.3.2,!=2.3.3,>=1.3 # BSD
+Django<1.9,>=1.8 # BSD
 Pint>=0.5 # BSD
-django-babel>=0.4.0
-django-compressor>=1.4
-django-openstack-auth>=2.0.0
+django-babel>=0.4.0 # BSD
+django-compressor>=2.0 # MIT
+django-openstack-auth>=2.0.0 # Apache-2.0
 django-pyscss>=2.0.2 # BSD License (2 clause)
-httplib2>=0.7.5
-iso8601>=0.1.9
-netaddr!=0.7.16,>=0.7.12
-oslo.concurrency>=2.3.0 # Apache-2.0
-oslo.config>=3.2.0 # Apache-2.0
-oslo.i18n>=1.5.0 # Apache-2.0
+httplib2>=0.7.5 # MIT
+iso8601>=0.1.9 # MIT
+netaddr!=0.7.16,>=0.7.12 # BSD
+oslo.concurrency>=3.7.1 # Apache-2.0
+oslo.config>=3.7.0 # Apache-2.0
+oslo.i18n>=2.1.0 # Apache-2.0
 oslo.policy>=0.5.0 # Apache-2.0
 oslo.serialization>=1.10.0 # Apache-2.0
-oslo.utils>=3.2.0 # Apache-2.0
+oslo.utils>=3.5.0 # Apache-2.0
 pyScss>=1.3.4 # MIT License
-python-ceilometerclient>=2.0.0
-python-cinderclient>=1.3.1
-python-glanceclient>=1.2.0
-python-heatclient>=0.6.0
-python-keystoneclient!=1.8.0,>=1.6.0
-python-neutronclient>=2.6.0
-python-novaclient!=2.33.0,>=2.29.0
-python-swiftclient>=2.2.0
-pytz>=2013.6
-PyYAML>=3.1.0
-six>=1.9.0
+python-ceilometerclient>=2.2.1 # Apache-2.0
+python-cinderclient>=1.3.1 # Apache-2.0
+python-glanceclient>=2.0.0 # Apache-2.0
+python-heatclient>=0.6.0 # Apache-2.0
+python-keystoneclient!=1.8.0,!=2.1.0,<3.0.0,>=1.6.0 # Apache-2.0
+python-neutronclient!=4.1.0,>=2.6.0 # Apache-2.0
+python-novaclient!=2.33.0,>=2.29.0 # Apache-2.0
+python-swiftclient>=2.2.0 # Apache-2.0
+pytz>=2013.6 # MIT
+PyYAML>=3.1.0 # MIT
+six>=1.9.0 # MIT
 XStatic>=1.0.0 # MIT License
 XStatic-Angular>=1.3.7 # MIT License
 XStatic-Angular-Bootstrap>=0.11.0.2 # MIT License
@@ -55,7 +55,6 @@
 XStatic-JQuery.TableSorter>=2.14.5.1 # MIT License
 XStatic-jquery-ui>=1.10.1 # MIT License
 XStatic-JSEncrypt>=2.0.0.2 # MIT License
-XStatic-Magic-Search>=0.2.5.1 # Apache 2.0 License
 XStatic-mdi==1.1.70.1 # SIL OPEN FONT LICENSE Version 1.1
 XStatic-Rickshaw>=1.5.0 # BSD License (prior)
 XStatic-roboto-fontface>=0.4.3.2 # Apache 2.0 License
@@ -64,7 +63,3 @@
 XStatic-term.js>=0.0.4 # MIT License
 
 horizon-contrib>=2015.10.0
-
-# metadata update needs
-functools32==3.2.3-2
-jsonpointer==1.10
\ No newline at end of file
diff --git a/horizon/map.jinja b/horizon/map.jinja
index e7593f8..a3a8fe6 100644
--- a/horizon/map.jinja
+++ b/horizon/map.jinja
@@ -1,14 +1,19 @@
+{%- set dashboard_package = salt['pillar.get']('horizon:server:package', 'openstack-dashboard') %}
+
 {% set server = salt['grains.filter_by']({
     'Debian': {
-        'pkgs': ['apache2', 'openstack-dashboard', 'python-lesscpy', 'python-memcache'],
+        'pkgs': ['apache2', dashboard_package, 'python-lesscpy', 'python-memcache', 'gettext-base'],
         'pkgs_multi': ['python-memcache', 'python-psycopg2', 'python-imaging',
             'python-docutils', 'python-simplejson', 'build-essential',
             'libxslt1-dev', 'libxml2-dev', 'libffi-dev', 'libssl-dev',
             'gettext', 'python-lesscpy'],
-        'ssl_pkgs': ['openstack-dashboard'],
+        'ssl_pkgs': [dashboard_package],
         'service': 'apache2',
         'config': '/etc/openstack-dashboard/local_settings.py',
         'apache_config': '/etc/apache2/conf-available/openstack-dashboard.conf',
+        'apache_log_dir': '/var/log/apache2',
+        'apache_log_filename': 'openstack_dashboard',
+        'apache_log_format': '%h %t %m \\"%U%q\\" %H %>s %O %D \\"%{Referer}i\\" \\"%{User-Agent}i\\"',
         'certs_dir': '/etc/ssl/certs',
         'private_dir': '/etc/ssl/private',
         'port_config_file': '/etc/apache2/ports.conf',
@@ -16,7 +21,7 @@
         'cache': {'host': '127.0.0.1', 'port': 11211}
     },
     'RedHat': {
-        'pkgs': ['httpd', 'openstack-dashboard', 'python-lesscpy', 'python-memcached'],
+        'pkgs': ['httpd', dashboard_package, 'python-lesscpy', 'python-memcached'],
         'pkgs_multi': ['python-memcached', 'python-psycopg2', 'python-pillow',
             'python-docutils', 'python-simplejson', 'libxslt-devel', 'gcc',
             'libxml2-devel', 'libffi-devel', 'openssl-devel',
@@ -25,6 +30,9 @@
         'service': 'httpd',
         'config': '/etc/openstack-dashboard/local_settings',
         'apache_config': '/etc/httpd/conf.d/openstack-dashboard.conf',
+        'apache_log_dir': '/var/log/httpd',
+        'apache_log_filename': 'openstack_dashboard',
+        'apache_log_format': '%h %t %m \\"%U%q\\" %H %>s %O %D \\"%{Referer}i\\" \\"%{User-Agent}i\\"',
         'certs_dir': '/etc/pki/tls/certs',
         'private_dir': '/etc/pki/tls/private',
         'port_config_file': '/etc/httpd/conf/httpd.conf',
diff --git a/horizon/meta/heka.yml b/horizon/meta/heka.yml
new file mode 100644
index 0000000..100488f
--- /dev/null
+++ b/horizon/meta/heka.yml
@@ -0,0 +1,22 @@
+{%- from "horizon/map.jinja" import server with context %}
+log_collector:
+  decoder:
+    horizon_apache_access:
+      engine: sandbox
+      module_file: /usr/share/lma_collector/decoders/lma_apache_access.lua
+      module_dir: /usr/share/lma_collector/common;/usr/share/heka/lua_modules
+      adjust_timezone: true
+      config:
+        type: "log"
+        log_format: '{{ server.apache_log_format }}'
+        user_agent_transform: true
+        payload_keep: true
+  input:
+    horizon_apache_access:
+      engine: logstreamer
+      log_directory: "{{ server.apache_log_dir}}"
+      file_match: '{{ server.apache_log_filename }}_access(?P<Service>.*)\.log\.?(?P<Seq>\d*)'
+      differentiator: [ 'openstack.horizon', 'Service' ]
+      priority: ["^Seq"]
+      decoder: "horizon_apache_access_decoder"
+      splitter: "TokenSplitter"
diff --git a/horizon/meta/salt.yml b/horizon/meta/salt.yml
new file mode 100644
index 0000000..1c0e954
--- /dev/null
+++ b/horizon/meta/salt.yml
@@ -0,0 +1,6 @@
+orchestrate:
+  server:
+    priority: 730
+    require:
+    - salt: keystone.server
+
diff --git a/horizon/server/init.sls b/horizon/server/init.sls
index 8b77234..081891d 100644
--- a/horizon/server/init.sls
+++ b/horizon/server/init.sls
@@ -1,7 +1,7 @@
 include:
 {%- if pillar.horizon.server.app is defined %}
 {# uglier way, for development #}
-- horizon.server.multi.service_git
+- horizon.server.multi.service
 - horizon.server.multi.site
 {%- else %}
 {# production way #}
diff --git a/horizon/server/multi/init.sls b/horizon/server/multi/init.sls
index 63fa6f4..dcf8b74 100644
--- a/horizon/server/multi/init.sls
+++ b/horizon/server/multi/init.sls
@@ -2,6 +2,6 @@
 {%- if server.enabled %}
 
 include:
-- horizon.server.multi.service_git
+- horizon.server.multi.service
 
 {%- endif %}
diff --git a/horizon/server/multi/service_git.sls b/horizon/server/multi/service.sls
similarity index 100%
rename from horizon/server/multi/service_git.sls
rename to horizon/server/multi/service.sls
diff --git a/horizon/server/multi/site.sls b/horizon/server/multi/site.sls
index 178d5fb..4dc8595 100644
--- a/horizon/server/multi/site.sls
+++ b/horizon/server/multi/site.sls
@@ -54,8 +54,12 @@
   git.latest:
   - name: {{ app.source.address }}
   - target: /srv/horizon/sites/{{ app_name }}/extra
+  {%- if grains.saltversioninfo.0 > 2015 %}
+  - rev: HEAD
+  - branch: {{ app.source.revision }}
+  {%- else %}
   - rev: {{ app.source.revision }}
-  - depth: 1
+  {%- endif %}
   - submodules: True
   - require:
     - virtualenv: /srv/horizon/sites/{{ app_name }}
@@ -255,7 +259,12 @@
   {{ plugin.source.engine }}.latest:
   - name: {{ plugin.source.address }}
   - target: /srv/horizon/sites/{{ app_name }}/plugins/{{ plugin_name }}
+  {%- if grains.saltversioninfo.0 > 2015 %}
+  - rev: HEAD
+  - branch: {{ plugin.source.revision }}
+  {%- else %}
   - rev: {{ plugin.source.revision }}
+  {%- endif %}
   - submodules: True
   - require:
     - file: /srv/horizon/sites/{{ app_name }}/plugins
diff --git a/horizon/server/service.sls b/horizon/server/service.sls
index d549c57..86f0c21 100644
--- a/horizon/server/service.sls
+++ b/horizon/server/service.sls
@@ -49,13 +49,16 @@
     - pkg: horizon_packages
 
 {%- if grains.os_family == 'Debian' %}
-/etc/apache2/conf-enabled/openstack-dashboard.conf:
-  file.symlink:
-    - target: /etc/apache2/conf-available/openstack-dashboard.conf
-
 apache_enable_wsgi:
   apache_module.enable:
     - name: wsgi
+
+enable_horizon_apache_config:
+  apache_conf.enable:
+  - name: openstack-dashboard
+  - require:
+    - file: horizon_apache_config
+    - apache_module: apache_enable_wsgi
 {%- endif %}
 
 horizon_services:
@@ -83,4 +86,15 @@
     - require:
       - file: horizon_log_dir
 
+{%- if grains.get('virtual_subtype', None) == "Docker" %}
+
+horizon_entrypoint:
+  file.managed:
+  - name: /entrypoint.sh
+  - template: jinja
+  - source: salt://horizon/files/entrypoint.sh
+  - mode: 755
+
+{%- endif %}
+
 {%- endif %}
diff --git a/metadata/service/support.yml b/metadata/service/support.yml
index 2ebbaee..4f19089 100644
--- a/metadata/service/support.yml
+++ b/metadata/service/support.yml
@@ -4,7 +4,7 @@
       collectd:
         enabled: false
       heka:
-        enabled: false
+        enabled: true
       sensu:
         enabled: true
       sphinx:
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index 6710a50..8c07e58 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -18,7 +18,7 @@
 SALT_CONFIG_DIR=${SALT_CONFIG_DIR:-${BUILDDIR}/salt}
 SALT_CACHE_DIR=${SALT_CACHE_DIR:-${SALT_CONFIG_DIR}/cache}
 
-SALT_OPTS="${SALT_OPTS} --retcode-passthrough --local -c ${SALT_CONFIG_DIR}"
+SALT_OPTS="${SALT_OPTS} --retcode-passthrough --local -c ${SALT_CONFIG_DIR} --log-file=/dev/null"
 
 if [ "x${SALT_VERSION}" != "x" ]; then
     PIP_SALT_VERSION="==${SALT_VERSION}"