diff --git a/playbooks/sphinx-docs/neutron-horizon-hack.yaml b/playbooks/sphinx-docs/neutron-horizon-hack.yaml
new file mode 100644
index 00000000..da220726
--- /dev/null
+++ b/playbooks/sphinx-docs/neutron-horizon-hack.yaml
@@ -0,0 +1,4 @@
+# TODO(mordred) ZOMG DELETE THIS
+- hosts: all
+  roles:
+    - neutron-horizon-hack
diff --git a/playbooks/sphinx-docs/run.yaml b/playbooks/sphinx-docs/run.yaml
deleted file mode 100644
index 1527c3b8..00000000
--- a/playbooks/sphinx-docs/run.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-- hosts: all
-  roles:
-    - tox
-
-  post_tasks:
-
-    - name: check for whereto
-      stat:
-        path: "{{ zuul_work_dir }}/.tox/{{ tox_envlist }}/bin/whereto"
-      register: whereto
-
-    - name: Run tox again for whereto
-      include_role:
-        name: tox
-      vars:
-        tox_extra_args: whereto doc/source/_extra/.htaccess doc/test/redirect-tests.txt
-      when: whereto.stat.exists
diff --git a/roles/neutron-horizon-hack/README.rst b/roles/neutron-horizon-hack/README.rst
new file mode 100644
index 00000000..61a97379
--- /dev/null
+++ b/roles/neutron-horizon-hack/README.rst
@@ -0,0 +1,26 @@
+Hack around some requirements being declared in tox_install.sh
+
+.. note:: TODO(mordred) ZOMG DELETE THIS
+
+neutron and horizon plugin repos currently require running the tox_install.sh
+script where a list of additional dependencies are listed that are not in
+their requirements files. Luckily, tox_install.sh is designed to be run
+inside of a virtualenv, so we can just run it in the sphinx ~/.venv and
+get them installed. This will let us work towards a solution that does not
+involve a custom install script.
+
+**Role Variables**
+
+.. zuul:rolevar:: constraints_file
+
+   Optional path to a constraints file to use.
+
+.. zuul:rolevar:: zuul_work_virtualenv
+   :default: ~/.venv
+
+   Virtualenv that sphinx is installed in.
+
+.. zuul:rolevar:: zuul_work_dir
+   :default: {{ zuul.project.src_dir }}
+
+   Directory to operate in.
diff --git a/roles/neutron-horizon-hack/defaults/main.yaml b/roles/neutron-horizon-hack/defaults/main.yaml
new file mode 100644
index 00000000..e95f7bad
--- /dev/null
+++ b/roles/neutron-horizon-hack/defaults/main.yaml
@@ -0,0 +1,2 @@
+zuul_work_dir: "{{ zuul.project.src_dir }}"
+zuul_work_virtualenv: "{{ ansible_user_dir }}/.venv"
diff --git a/roles/neutron-horizon-hack/tasks/main.yaml b/roles/neutron-horizon-hack/tasks/main.yaml
new file mode 100644
index 00000000..c06b7811
--- /dev/null
+++ b/roles/neutron-horizon-hack/tasks/main.yaml
@@ -0,0 +1,27 @@
+- name: Check for tox_install.sh
+  stat:
+    path: "{{ zuul_work_dir }}/tools/tox_install.sh"
+    get_checksum: false
+    get_mime: false
+    get_md5: false
+  register: tox_install
+
+- name: Require Constraints File
+  when: tox_install.stat.exists and constraints_file is not defined
+  fail:
+    msg: tox_install.sh projects require a constraints file to be set
+
+- name: Ensure log directory exists for backwards compat
+  when: tox_install.stat.exists
+  file:
+    path: '{{ zuul_work_virtualenv }}/log'
+    state: directory
+
+- name: Install extra things needed by tox_install.sh
+  when: tox_install.stat.exists
+  shell:
+    executable: /bin/bash
+    cmd: |
+      source {{ zuul_work_virtualenv }}/bin/activate
+      tools/tox_install.sh {{ constraints_file }}
+    chdir: "{{ zuul_work_dir }}"
diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml
index 5c99fab8..e5a6941d 100644
--- a/zuul.d/jobs.yaml
+++ b/zuul.d/jobs.yaml
@@ -189,7 +189,7 @@
 
 - job:
     name: build-openstack-sphinx-docs
-    parent: tox-docs
+    parent: build-sphinx-docs
     branches: ^(?!driverfixes/).*$
     description: |
       Builds documentation using Sphinx per the OpenStack PTI and then
@@ -198,16 +198,14 @@
       It runs the prepare-docs-for-afs role so that AFS stamp files
       can be examined if desired, and also validates htaccess files
       using the whereto tool.
-    run: playbooks/sphinx-docs/run.yaml
     success-url: html/
     required-projects:
       - name: openstack/requirements
+    pre-run: playbooks/sphinx-docs/neutron-horizon-hack.yaml
     roles:
       - zuul: openstack-infra/zuul-jobs
     vars:
-      tox_constraints_file: '{{ ansible_user_dir }}/src/git.openstack.org/openstack/requirements/upper-constraints.txt'
-      tox_envlist: venv
-      tox_extra_args: -vv python setup.py build_sphinx
+      constraints_file: '{{ ansible_user_dir }}/src/git.openstack.org/openstack/requirements/upper-constraints.txt'
 
 - job:
     name: tox-py35-on-zuul