Merge "generate-devstack-plugins-list: Retry on opendev.org 500"
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 9059f8c..56043ba 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -165,7 +165,7 @@
 # Grouping the document tree into LaTeX files. List of tuples
 # (source start file, target name, title, author, documentclass [howto/manual]).
 latex_documents = [
-  ('index', 'DevStack-doc.tex', u'DevStack Docs',
+  ('index', 'doc-devstack.tex', u'DevStack Docs',
    u'OpenStack DevStack Team', 'manual'),
 ]
 
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 8f95858..6694022 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -11,9 +11,8 @@
    and how to go beyond this setup. Both should be a set of quick
    links to other documents to let people explore from there.
 
-==========
- DevStack
-==========
+DevStack
+========
 
 .. image:: assets/images/logo-blue.png
 
@@ -32,7 +31,7 @@
    are dedicated to this purpose.
 
 Quick Start
-===========
++++++++++++
 
 Install Linux
 -------------
@@ -153,7 +152,7 @@
 <hacking>`.
 
 Contents
---------
+++++++++
 
 .. toctree::
    :glob:
diff --git a/lib/horizon b/lib/horizon
index 293a627..b2bf7bc 100644
--- a/lib/horizon
+++ b/lib/horizon
@@ -43,8 +43,8 @@
     local value=$4
 
     if [ -z "$section" ]; then
-        sed -e "/^$option/d" -i $local_settings
-        echo -e "\n$option=$value" >> $file
+        sed -e "/^$option/d" -i $file
+        echo "$option = $value" >> $file
     elif grep -q "^$section" $file; then
         local line
         line=$(sed -ne "/^$section/,/^}/ { /^ *'$option':/ p; }" $file)
@@ -84,6 +84,9 @@
     local local_settings=$HORIZON_DIR/openstack_dashboard/local/local_settings.py
     cp $HORIZON_SETTINGS $local_settings
 
+    # Ensure local_setting.py file ends with EOL (newline)
+    echo >> $local_settings
+
     _horizon_config_set $local_settings "" WEBROOT \"$HORIZON_APACHE_ROOT/\"
 
     _horizon_config_set $local_settings "" COMPRESS_OFFLINE True
@@ -91,7 +94,6 @@
 
     _horizon_config_set $local_settings "" OPENSTACK_HOST \"${KEYSTONE_SERVICE_HOST}\"
 
-    _horizon_config_set $local_settings "" OPENSTACK_API_VERSIONS {\"identity\":3}
     _horizon_config_set $local_settings "" OPENSTACK_KEYSTONE_URL "\"${KEYSTONE_SERVICE_URI}/v3\""
 
     # note(trebskit): if HOST_IP points at non-localhost ip address, horizon cannot be accessed
diff --git a/lib/neutron_plugins/services/l3 b/lib/neutron_plugins/services/l3
index ec289f6..69536bb 100644
--- a/lib/neutron_plugins/services/l3
+++ b/lib/neutron_plugins/services/l3
@@ -395,8 +395,6 @@
 
     # This logic is specific to using the l3-agent for layer 3
     if is_service_enabled q-l3 || is_service_enabled neutron-l3; then
-        # Ensure IPv6 forwarding is enabled on the host
-        sudo sysctl -w net.ipv6.conf.all.forwarding=1
         # if the Linux host considers itself to be a router then it will
         # ignore all router advertisements
         # Ensure IPv6 RAs are accepted on interfaces with a default route.
@@ -409,6 +407,8 @@
             # device name would be reinterpreted as a slash, causing an error.
             sudo sysctl -w net/ipv6/conf/$d/accept_ra=2
         done
+        # Ensure IPv6 forwarding is enabled on the host
+        sudo sysctl -w net.ipv6.conf.all.forwarding=1
         # Configure and enable public bridge
         # Override global IPV6_ROUTER_GW_IP with the true value from neutron
         IPV6_ROUTER_GW_IP=$(openstack --os-cloud devstack-admin --os-region "$REGION_NAME" port list -c 'Fixed IP Addresses' | grep $ipv6_pub_subnet_id | awk -F'ip_address' '{ print $2 }' | cut -f2 -d\' | tr '\n' ' ')
diff --git a/stack.sh b/stack.sh
index 11783fd..b7b37e2 100755
--- a/stack.sh
+++ b/stack.sh
@@ -796,9 +796,6 @@
     PYPI_ALTERNATIVE_URL=${PYPI_ALTERNATIVE_URL:-""} $TOP_DIR/tools/install_pip.sh
 fi
 
-# Install subunit for the subunit output stream
-pip_install -U os-testr
-
 TRACK_DEPENDS=${TRACK_DEPENDS:-False}
 
 # Install Python packages into a virtualenv so that we can track them
@@ -816,6 +813,9 @@
 source $TOP_DIR/tools/fixup_stuff.sh
 fixup_all
 
+# Install subunit for the subunit output stream
+pip_install -U os-testr
+
 if [[ "$USE_SYSTEMD" == "True" ]]; then
     pip_install_gr systemd-python
     # the default rate limit of 1000 messages / 30 seconds is not
diff --git a/tools/fixup_stuff.sh b/tools/fixup_stuff.sh
index d7b824c..d298937 100755
--- a/tools/fixup_stuff.sh
+++ b/tools/fixup_stuff.sh
@@ -256,6 +256,7 @@
     # overwriting works.  So this hacks around those packages that
     # have been dragged in by some other system dependency
     sudo rm -rf /usr/lib/python3.6/site-packages/ply-*.egg-info
+    sudo rm -rf /usr/lib/python3.6/site-packages/six-*.egg-info
 }
 
 # The version of pip(1.5.4) supported by python-virtualenv(1.11.4) has
diff --git a/tox.ini b/tox.ini
index d81107f..26baa2a 100644
--- a/tox.ini
+++ b/tox.ini
@@ -43,6 +43,14 @@
 commands =
   sphinx-build -W -b html -d doc/build/doctrees doc/source doc/build/html
 
+[testenv:pdf-docs]
+basepython = python3
+deps = {[testenv:docs]deps}
+whitelist_externals =
+   make
+commands =
+   sphinx-build -W -b latex doc/source doc/build/pdf
+   make -C doc/build/pdf
 
 [testenv:venv]
 basepython = python3