Merge "Move process-stackviz role from Tempest to Devstack"
diff --git a/.zuul.yaml b/.zuul.yaml
index f3610af..43e5d4c 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -9,6 +9,16 @@
           - controller
 
 - nodeset:
+    name: openstack-single-node-focal
+    nodes:
+      - name: controller
+        label: ubuntu-focal
+    groups:
+      - name: tempest
+        nodes:
+          - controller
+
+- nodeset:
     name: openstack-single-node-bionic
     nodes:
       - name: controller
@@ -99,6 +109,36 @@
           - compute1
 
 - nodeset:
+    name: openstack-two-node-focal
+    nodes:
+      - name: controller
+        label: ubuntu-focal
+      - name: compute1
+        label: ubuntu-focal
+    groups:
+      # Node where tests are executed and test results collected
+      - name: tempest
+        nodes:
+          - controller
+      # Nodes running the compute service
+      - name: compute
+        nodes:
+          - controller
+          - compute1
+      # Nodes that are not the controller
+      - name: subnode
+        nodes:
+          - compute1
+      # Switch node for multinode networking setup
+      - name: switch
+        nodes:
+          - controller
+      # Peer nodes for multinode networking setup
+      - name: peers
+        nodes:
+          - compute1
+
+- nodeset:
     name: openstack-two-node-bionic
     nodes:
       - name: controller
@@ -159,6 +199,41 @@
           - compute1
 
 - nodeset:
+    name: openstack-three-node-focal
+    nodes:
+      - name: controller
+        label: ubuntu-focal
+      - name: compute1
+        label: ubuntu-focal
+      - name: compute2
+        label: ubuntu-focal
+    groups:
+      # Node where tests are executed and test results collected
+      - name: tempest
+        nodes:
+          - controller
+      # Nodes running the compute service
+      - name: compute
+        nodes:
+          - controller
+          - compute1
+          - compute2
+      # Nodes that are not the controller
+      - name: subnode
+        nodes:
+          - compute1
+          - compute2
+      # Switch node for multinode networking setup
+      - name: switch
+        nodes:
+          - controller
+      # Peer nodes for multinode networking setup
+      - name: peers
+        nodes:
+          - compute1
+          - compute2
+
+- nodeset:
     name: openstack-three-node-bionic
     nodes:
       - name: controller
@@ -483,9 +558,6 @@
       devstack_localrc:
         SERVICE_IP_VERSION: 6
         SERVICE_HOST: ""
-        # IPv6 and certificates known issue with python2
-        # https://bugs.launchpad.net/devstack/+bug/1794929
-        USE_PYTHON3: true
 
 - job:
     name: devstack-multinode
@@ -515,6 +587,15 @@
     voting: false
 
 - job:
+    name: devstack-platform-focal
+    parent: tempest-full-py3
+    description: Ubuntu Focal Fossa platform test
+    nodeset: openstack-single-node-focal
+    vars:
+      tempest_black_regex: "(tempest.api.compute.volumes.test_attach_volume.AttachVolumeMultiAttachTest.test_resize_server_with_multiattached_volume|tempest.api.compute.servers.test_server_rescue_negative.ServerRescueNegativeTestJSON|tempest.api.compute.servers.test_server_rescue.ServerStableDeviceRescueTest.test_stable_device_rescue_disk_virtio_with_volume_attached)"
+    voting: false
+
+- job:
     name: devstack-platform-fedora-latest
     parent: tempest-full-py3
     description: Fedora latest platform test
@@ -605,6 +686,7 @@
         - devstack-platform-opensuse-15
         - devstack-platform-fedora-latest
         - devstack-platform-centos-8
+        - devstack-platform-focal
         - devstack-multinode
         - devstack-unit-tests
         - openstack-tox-bashate
@@ -630,6 +712,11 @@
             irrelevant-files:
               - ^.*\.rst$
               - ^doc/.*$
+        - neutron-ovn-tempest-ovs-release:
+            voting: false
+            irrelevant-files:
+              - ^.*\.rst$
+              - ^doc/.*$
         - tempest-multinode-full-py3:
             voting: false
             irrelevant-files:
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 45f4ffe..ec4a9c8 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -137,7 +137,7 @@
 
     ::
 
-        OS_AUTH_URL=http://$SERVICE_HOST:5000/v3.0
+        OS_AUTH_URL=http://$SERVICE_HOST/identity/v3.0
 
 KEYSTONECLIENT\_DEBUG, NOVACLIENT\_DEBUG
     Set command-line client log level to ``DEBUG``. These are commented
@@ -430,17 +430,6 @@
 
   ADDITIONAL_VENV_PACKAGES="python-foo, python-bar"
 
-Use python3
-------------
-
-By default ``stack.sh`` uses python2 (the exact version set by the
-``PYTHON2_VERSION``). This can be overriden so devstack will run
-python3 (the exact version set by ``PYTHON3_VERSION``).
-
-::
-
-  USE_PYTHON3=True
-
 A clean install every time
 --------------------------
 
@@ -696,16 +685,6 @@
 KEYSTONE_REGION_NAME has a default value the same as REGION_NAME thus we omit
 it in the configuration of RegionOne.
 
-Disabling Identity API v2
-+++++++++++++++++++++++++
-
-The Identity API v2 is deprecated as of Mitaka and it is recommended to only
-use the v3 API. It is possible to setup keystone without v2 API, by doing:
-
-::
-
-    ENABLE_IDENTITY_V2=False
-
 .. _arch-configuration:
 
 Architectures
diff --git a/doc/source/guides/devstack-with-lbaas-v2.rst b/doc/source/guides/devstack-with-lbaas-v2.rst
index 7fde6f1..5d96ca7 100644
--- a/doc/source/guides/devstack-with-lbaas-v2.rst
+++ b/doc/source/guides/devstack-with-lbaas-v2.rst
@@ -41,9 +41,6 @@
     # If you are enabling barbican for TLS offload in Octavia, include it here.
     # enable_plugin barbican https://opendev.org/openstack/barbican
 
-    # If you have python3 available:
-    # USE_PYTHON3=True
-
     # ===== BEGIN localrc =====
     DATABASE_PASSWORD=password
     ADMIN_PASSWORD=password
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 7923cb8..8b8acde 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -38,8 +38,7 @@
 
 Start with a clean and minimal install of a Linux system. DevStack
 attempts to support the two latest LTS releases of Ubuntu, the
-latest/current Fedora version, CentOS/RHEL 7, as well as Debian and
-OpenSUSE.
+latest/current Fedora version, CentOS/RHEL 8 and OpenSUSE.
 
 If you do not have a preference, Ubuntu 18.04 (Bionic Beaver) is the
 most tested, and will probably go the smoothest.
diff --git a/doc/source/plugin-registry.rst b/doc/source/plugin-registry.rst
index 05a19ac..eda5773 100644
--- a/doc/source/plugin-registry.rst
+++ b/doc/source/plugin-registry.rst
@@ -41,7 +41,6 @@
 openstack/devstack-plugin-open-cas       `https://opendev.org/openstack/devstack-plugin-open-cas <https://opendev.org/openstack/devstack-plugin-open-cas>`__
 openstack/devstack-plugin-pika           `https://opendev.org/openstack/devstack-plugin-pika <https://opendev.org/openstack/devstack-plugin-pika>`__
 openstack/devstack-plugin-zmq            `https://opendev.org/openstack/devstack-plugin-zmq <https://opendev.org/openstack/devstack-plugin-zmq>`__
-openstack/dragonflow                     `https://opendev.org/openstack/dragonflow <https://opendev.org/openstack/dragonflow>`__
 openstack/ec2-api                        `https://opendev.org/openstack/ec2-api <https://opendev.org/openstack/ec2-api>`__
 openstack/freezer                        `https://opendev.org/openstack/freezer <https://opendev.org/openstack/freezer>`__
 openstack/freezer-api                    `https://opendev.org/openstack/freezer-api <https://opendev.org/openstack/freezer-api>`__
@@ -87,8 +86,6 @@
 openstack/networking-sfc                 `https://opendev.org/openstack/networking-sfc <https://opendev.org/openstack/networking-sfc>`__
 openstack/neutron                        `https://opendev.org/openstack/neutron <https://opendev.org/openstack/neutron>`__
 openstack/neutron-dynamic-routing        `https://opendev.org/openstack/neutron-dynamic-routing <https://opendev.org/openstack/neutron-dynamic-routing>`__
-openstack/neutron-fwaas                  `https://opendev.org/openstack/neutron-fwaas <https://opendev.org/openstack/neutron-fwaas>`__
-openstack/neutron-fwaas-dashboard        `https://opendev.org/openstack/neutron-fwaas-dashboard <https://opendev.org/openstack/neutron-fwaas-dashboard>`__
 openstack/neutron-tempest-plugin         `https://opendev.org/openstack/neutron-tempest-plugin <https://opendev.org/openstack/neutron-tempest-plugin>`__
 openstack/neutron-vpnaas                 `https://opendev.org/openstack/neutron-vpnaas <https://opendev.org/openstack/neutron-vpnaas>`__
 openstack/neutron-vpnaas-dashboard       `https://opendev.org/openstack/neutron-vpnaas-dashboard <https://opendev.org/openstack/neutron-vpnaas-dashboard>`__
diff --git a/files/apache-keystone.template b/files/apache-keystone.template
index 1284360..cf26c21 100644
--- a/files/apache-keystone.template
+++ b/files/apache-keystone.template
@@ -1,39 +1,9 @@
-Listen %PUBLICPORT%
-Listen %ADMINPORT%
 LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\" %D(us)" keystone_combined
 
 <Directory %KEYSTONE_BIN%>
     Require all granted
 </Directory>
 
-<VirtualHost *:%PUBLICPORT%>
-    WSGIDaemonProcess keystone-public processes=3 threads=1 user=%USER% display-name=%{GROUP} %VIRTUALENV%
-    WSGIProcessGroup keystone-public
-    WSGIScriptAlias / %KEYSTONE_BIN%/keystone-wsgi-public
-    WSGIApplicationGroup %{GLOBAL}
-    WSGIPassAuthorization On
-    ErrorLogFormat "%M"
-    ErrorLog /var/log/%APACHE_NAME%/keystone.log
-    CustomLog /var/log/%APACHE_NAME%/keystone_access.log keystone_combined
-    %SSLENGINE%
-    %SSLCERTFILE%
-    %SSLKEYFILE%
-</VirtualHost>
-
-<VirtualHost *:%ADMINPORT%>
-    WSGIDaemonProcess keystone-admin processes=3 threads=1 user=%USER% display-name=%{GROUP} %VIRTUALENV%
-    WSGIProcessGroup keystone-admin
-    WSGIScriptAlias / %KEYSTONE_BIN%/keystone-wsgi-admin
-    WSGIApplicationGroup %{GLOBAL}
-    WSGIPassAuthorization On
-    ErrorLogFormat "%M"
-    ErrorLog /var/log/%APACHE_NAME%/keystone.log
-    CustomLog /var/log/%APACHE_NAME%/keystone_access.log keystone_combined
-    %SSLENGINE%
-    %SSLCERTFILE%
-    %SSLKEYFILE%
-</VirtualHost>
-
 %SSLLISTEN%<VirtualHost *:443>
 %SSLLISTEN%    %SSLENGINE%
 %SSLLISTEN%    %SSLCERTFILE%
diff --git a/files/debs/general b/files/debs/general
index 2d8cd80..4bf1ff4 100644
--- a/files/debs/general
+++ b/files/debs/general
@@ -27,6 +27,7 @@
 pkg-config
 psmisc
 python3-dev
+python3-pip
 python3-venv
 tar
 tcpdump
diff --git a/files/debs/nova b/files/debs/nova
index dce8f6a..a7aebbf 100644
--- a/files/debs/nova
+++ b/files/debs/nova
@@ -17,7 +17,6 @@
 parted
 pm-utils
 python3-mysqldb
-qemu # dist:wheezy,jessie NOPRIME
 qemu-kvm # NOPRIME
 rabbitmq-server # NOPRIME
 socat # used by ajaxterm
diff --git a/files/debs/ovn b/files/debs/ovn
new file mode 100644
index 0000000..81eea5e
--- /dev/null
+++ b/files/debs/ovn
@@ -0,0 +1,3 @@
+ovn-central
+ovn-controller-vtep
+ovn-host
diff --git a/files/rpms/general b/files/rpms/general
index 303510c..c42ce52 100644
--- a/files/rpms/general
+++ b/files/rpms/general
@@ -24,6 +24,7 @@
 postgresql-devel  # psycopg2
 psmisc
 python3-devel
+python3-pip
 redhat-rpm-config # missing dep for gcc hardening flags, see rhbz#1217376
 systemd-devel # for systemd-python
 tar
diff --git a/files/rpms/ovn b/files/rpms/ovn
new file mode 100644
index 0000000..698e57b
--- /dev/null
+++ b/files/rpms/ovn
@@ -0,0 +1,3 @@
+ovn-central
+ovn-host
+ovn-vtep
diff --git a/functions-common b/functions-common
index dea5aa9..6595c3d 100644
--- a/functions-common
+++ b/functions-common
@@ -47,7 +47,7 @@
 
 # Save these variables to .stackenv
 STACK_ENV_VARS="BASE_SQL_CONN DATA_DIR DEST ENABLED_SERVICES HOST_IP \
-    KEYSTONE_AUTH_URI KEYSTONE_SERVICE_URI \
+    KEYSTONE_SERVICE_URI \
     LOGFILE OS_CACERT SERVICE_HOST STACK_USER TLS_IP \
     HOST_IPV6 SERVICE_IP_VERSION"
 
diff --git a/inc/python b/inc/python
index dd77296..f98d28d 100644
--- a/inc/python
+++ b/inc/python
@@ -62,7 +62,7 @@
     $xtrace
 
     local PYTHON_PATH=/usr/local/bin
-    ( is_fedora && ! python3_enabled ) || is_suse && PYTHON_PATH=/usr/bin
+    is_suse && PYTHON_PATH=/usr/bin
     echo $PYTHON_PATH
 }
 
@@ -169,16 +169,9 @@
         local cmd_pip=$PIP_VIRTUAL_ENV/bin/pip
         local sudo_pip="env"
     else
-        local cmd_pip
-        local sudo_pip="sudo -H"
-        if python3_enabled; then
-            echo "Using python $PYTHON3_VERSION to install $package_dir because python3_enabled=True"
-            sudo_pip="$sudo_pip LC_ALL=en_US.UTF-8"
-            cmd_pip=$(get_pip_command $PYTHON3_VERSION)
-        else
-            echo "Using python $PYTHON2_VERSION to install $package_dir because python3_enabled=False"
-            cmd_pip=$(get_pip_command $PYTHON2_VERSION)
-        fi
+        local cmd_pip="python$PYTHON3_VERSION -m pip"
+        local sudo_pip="sudo -H LC_ALL=en_US.UTF-8"
+        echo "Using python $PYTHON3_VERSION to install $package_dir"
     fi
 
     cmd_pip="$cmd_pip install"
@@ -213,14 +206,8 @@
         local cmd_pip=$PIP_VIRTUAL_ENV/bin/pip
         local sudo_pip="env"
     else
-        local cmd_pip
-        local sudo_pip="sudo -H"
-        if python3_enabled; then
-            sudo_pip="$sudo_pip LC_ALL=en_US.UTF-8"
-            cmd_pip=$(get_pip_command $PYTHON3_VERSION)
-        else
-            cmd_pip=$(get_pip_command $PYTHON2_VERSION)
-        fi
+        local cmd_pip="python$PYTHON3_VERSION -m pip"
+        local sudo_pip="sudo -H LC_ALL=en_US.UTF-8"
     fi
     # don't error if we can't uninstall, it might not be there
     $sudo_pip $cmd_pip uninstall -y $name || /bin/true
@@ -457,37 +444,15 @@
 }
 
 # Report whether python 3 should be used
+# TODO(frickler): drop this once all legacy uses are removed
 function python3_enabled {
-    if [[ $USE_PYTHON3 == "True" ]]; then
-        return 0
-    else
-        return 1
-    fi
+    return 0
 }
 
 # Provide requested python version and sets PYTHON variable
 function install_python {
-    # NOTE: install_python function should finally just do what install_python3
-    # does as soon Python 2 support has been dropped
-    if python3_enabled; then
-        install_python3
-        export PYTHON=$(which python${PYTHON3_VERSION} 2>/dev/null ||
-                        which python3 2>/dev/null)
-        if [[ "${DISTRO}" =~ (rhel8) ]]; then
-            # Use Python 3 as default python command so that we have only one
-            # python alternative to use on the system for either python and
-            # python3
-            sudo alternatives --set python "${PYTHON}"
-        else
-            # Install anyway Python 2 for legacy scripts that still requires
-            # python instead of python3 command
-            install_package python
-        fi
-    else
-        echo "WARNING - Python 2 support has been deprecated in favor of Python 3"
-        install_package python
-        export PYTHON=$(which python 2>/dev/null)
-    fi
+    install_python3
+    export PYTHON=$(which python${PYTHON3_VERSION} 2>/dev/null)
 }
 
 # Install python3 packages
diff --git a/lib/apache b/lib/apache
index 41c2e3d..cc28200 100644
--- a/lib/apache
+++ b/lib/apache
@@ -89,18 +89,15 @@
     #
     # For package installs, the distro ships both plugins and you need
     # to select the right one ... it will not be autodetected.
-    if python3_enabled; then
-        UWSGI_PYTHON_PLUGIN=python3
-    else
-        UWSGI_PYTHON_PLUGIN=python
-    fi
+    UWSGI_PYTHON_PLUGIN=python3
 
     if is_ubuntu; then
-        install_package uwsgi \
-                        uwsgi-plugin-python \
-                        uwsgi-plugin-python3 \
-                        libapache2-mod-proxy-uwsgi
-    elif [[ $os_VENDOR == "Fedora" ]]; then
+        local pkg_list="uwsgi uwsgi-plugin-python3 libapache2-mod-proxy-uwsgi"
+        if "$DISTRO" == 'bionic'; then
+            pkg_list="${pkg_list} uwsgi-plugin-python"
+        fi
+        install_package ${pkg_list}
+    elif is_fedora; then
         # Note httpd comes with mod_proxy_uwsgi and it is loaded by
         # default; the mod_proxy_uwsgi package actually conflicts now.
         # See:
@@ -114,9 +111,7 @@
                         uwsgi-python3 \
                         apache2-mod_uwsgi
     else
-        # Centos actually has the module in epel, but there was a big
-        # push to disable epel by default. As such, compile from source
-        # there.
+        # Compile uwsgi from source.
         local dir
         dir=$(mktemp -d)
         pushd $dir
@@ -151,14 +146,10 @@
     if is_ubuntu; then
         # Install apache2, which is NOPRIME'd
         install_package apache2
-        if python3_enabled; then
-            if is_package_installed libapache2-mod-wsgi; then
-                uninstall_package libapache2-mod-wsgi
-            fi
-            install_package libapache2-mod-wsgi-py3
-        else
-            install_package libapache2-mod-wsgi
+        if is_package_installed libapache2-mod-wsgi; then
+            uninstall_package libapache2-mod-wsgi
         fi
+        install_package libapache2-mod-wsgi-py3
     elif is_fedora; then
         sudo rm -f /etc/httpd/conf.d/000-*
         install_package httpd mod_wsgi
diff --git a/lib/cinder b/lib/cinder
index c2e55f9..b1e3d0d 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -419,7 +419,7 @@
     if [[ "$CINDER_ISCSI_HELPER" == "tgtadm" ]]; then
         install_package tgt
     elif [[ "$CINDER_ISCSI_HELPER" == "lioadm" ]]; then
-        if [[ ${DISTRO} == "bionic" ]]; then
+        if is_ubuntu; then
             # TODO(frickler): Workaround for https://launchpad.net/bugs/1819819
             sudo mkdir -p /etc/target
 
diff --git a/lib/glance b/lib/glance
index fee2cfd..6d252e3 100644
--- a/lib/glance
+++ b/lib/glance
@@ -186,25 +186,19 @@
     if is_service_enabled s-proxy; then
         iniset $GLANCE_API_CONF glance_store default_store swift
         iniset $GLANCE_API_CONF glance_store swift_store_create_container_on_put True
-        if python3_enabled; then
-            iniset $GLANCE_API_CONF glance_store swift_store_auth_insecure True
-        fi
 
         iniset $GLANCE_API_CONF glance_store swift_store_config_file $GLANCE_SWIFT_STORE_CONF
         iniset $GLANCE_API_CONF glance_store default_swift_reference ref1
         iniset $GLANCE_API_CONF glance_store stores "file, http, swift"
+        if is_service_enabled tls-proxy; then
+            iniset $GLANCE_API_CONF glance_store swift_store_cacert $SSL_BUNDLE_FILE
+        fi
         iniset $GLANCE_API_CONF DEFAULT graceful_shutdown_timeout "$SERVICE_GRACEFUL_SHUTDOWN_TIMEOUT"
 
         iniset $GLANCE_SWIFT_STORE_CONF ref1 user $SERVICE_PROJECT_NAME:glance-swift
 
         iniset $GLANCE_SWIFT_STORE_CONF ref1 key $SERVICE_PASSWORD
-        if python3_enabled; then
-            # NOTE(dims): Currently the glance_store+swift does not support either an insecure flag
-            # or ability to specify the CACERT. So fallback to http:// url
-            iniset $GLANCE_SWIFT_STORE_CONF ref1 auth_address ${KEYSTONE_SERVICE_URI/https/http}/v3
-        else
-            iniset $GLANCE_SWIFT_STORE_CONF ref1 auth_address $KEYSTONE_SERVICE_URI/v3
-        fi
+        iniset $GLANCE_SWIFT_STORE_CONF ref1 auth_address $KEYSTONE_SERVICE_URI/v3
         iniset $GLANCE_SWIFT_STORE_CONF ref1 auth_version 3
     fi
 
@@ -214,8 +208,7 @@
 
     if is_service_enabled tls-proxy; then
         iniset $GLANCE_API_CONF DEFAULT bind_port $GLANCE_SERVICE_PORT_INT
-
-        iniset $GLANCE_API_CONF keystone_authtoken identity_uri $KEYSTONE_AUTH_URI
+        iniset $GLANCE_API_CONF keystone_authtoken identity_uri $KEYSTONE_SERVICE_URI
     fi
 
     # Format logging
@@ -227,7 +220,7 @@
     iniset $GLANCE_CACHE_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
     iniset $GLANCE_CACHE_CONF DEFAULT use_syslog $SYSLOG
     iniset $GLANCE_CACHE_CONF DEFAULT image_cache_dir $GLANCE_CACHE_DIR/
-    iniset $GLANCE_CACHE_CONF DEFAULT auth_url $KEYSTONE_AUTH_URI
+    iniset $GLANCE_CACHE_CONF DEFAULT auth_url $KEYSTONE_SERVICE_URI
     iniset $GLANCE_CACHE_CONF DEFAULT admin_tenant_name $SERVICE_PROJECT_NAME
     iniset $GLANCE_CACHE_CONF DEFAULT admin_user glance
     iniset $GLANCE_CACHE_CONF DEFAULT admin_password $SERVICE_PASSWORD
diff --git a/lib/keystone b/lib/keystone
index 1910f34..29407a0 100644
--- a/lib/keystone
+++ b/lib/keystone
@@ -83,14 +83,10 @@
 
 # Set Keystone interface configuration
 KEYSTONE_AUTH_HOST=${KEYSTONE_AUTH_HOST:-$SERVICE_HOST}
-KEYSTONE_AUTH_PORT=${KEYSTONE_AUTH_PORT:-35357}
-KEYSTONE_AUTH_PORT_INT=${KEYSTONE_AUTH_PORT_INT:-35358}
 KEYSTONE_AUTH_PROTOCOL=${KEYSTONE_AUTH_PROTOCOL:-$SERVICE_PROTOCOL}
 
 # Public facing bits
 KEYSTONE_SERVICE_HOST=${KEYSTONE_SERVICE_HOST:-$SERVICE_HOST}
-KEYSTONE_SERVICE_PORT=${KEYSTONE_SERVICE_PORT:-5000}
-KEYSTONE_SERVICE_PORT_INT=${KEYSTONE_SERVICE_PORT_INT:-5001}
 KEYSTONE_SERVICE_PROTOCOL=${KEYSTONE_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
 
 # Bind hosts
@@ -115,7 +111,7 @@
 KEYSTONE_AUTH_URI=$KEYSTONE_SERVICE_URI
 
 # V3 URIs
-KEYSTONE_AUTH_URI_V3=$KEYSTONE_AUTH_URI/v3
+KEYSTONE_AUTH_URI_V3=$KEYSTONE_SERVICE_URI/v3
 KEYSTONE_SERVICE_URI_V3=$KEYSTONE_SERVICE_URI/v3
 
 # Security compliance
@@ -170,22 +166,14 @@
     local keystone_ssl=""
     local keystone_certfile=""
     local keystone_keyfile=""
-    local keystone_service_port=$KEYSTONE_SERVICE_PORT
-    local keystone_auth_port=$KEYSTONE_AUTH_PORT
     local venv_path=""
 
-    if is_service_enabled tls-proxy; then
-        keystone_service_port=$KEYSTONE_SERVICE_PORT_INT
-        keystone_auth_port=$KEYSTONE_AUTH_PORT_INT
-    fi
     if [[ ${USE_VENV} = True ]]; then
         venv_path="python-path=${PROJECT_VENV["keystone"]}/lib/$(python_version)/site-packages"
     fi
 
     sudo cp $FILES/apache-keystone.template $keystone_apache_conf
     sudo sed -e "
-        s|%PUBLICPORT%|$keystone_service_port|g;
-        s|%ADMINPORT%|$keystone_auth_port|g;
         s|%APACHE_NAME%|$APACHE_NAME|g;
         s|%SSLLISTEN%|$keystone_ssl_listen|g;
         s|%SSLENGINE%|$keystone_ssl|g;
@@ -222,21 +210,8 @@
 
     iniset_rpc_backend keystone $KEYSTONE_CONF oslo_messaging_notifications
 
-    local service_port=$KEYSTONE_SERVICE_PORT
-    local auth_port=$KEYSTONE_AUTH_PORT
-
-    if is_service_enabled tls-proxy; then
-        # Set the service ports for a proxy to take the originals
-        service_port=$KEYSTONE_SERVICE_PORT_INT
-        auth_port=$KEYSTONE_AUTH_PORT_INT
-    fi
-
     # Override the endpoints advertised by keystone (the public_endpoint and
-    # admin_endpoint) so that clients use the correct endpoint. By default, the
-    # keystone server uses the public_port and admin_port which isn't going to
-    # work when you want to use a different port (in the case of proxy), or you
-    # don't want the port (in the case of putting keystone on a path in
-    # apache).
+    # admin_endpoint) so that clients use the correct endpoint.
     iniset $KEYSTONE_CONF DEFAULT public_endpoint $KEYSTONE_SERVICE_URI
     iniset $KEYSTONE_CONF DEFAULT admin_endpoint $KEYSTONE_AUTH_URI
 
@@ -270,12 +245,6 @@
 
     iniset $KEYSTONE_CONF credential key_repository "$KEYSTONE_CONF_DIR/credential-keys/"
 
-    # Configure the project created by the 'keystone-manage bootstrap' as the cloud-admin project.
-    # The users from this project are globally admin as before, but it also
-    # allows policy changes in order to clarify the adminess scope.
-    #iniset $KEYSTONE_CONF resource admin_project_domain_name Default
-    #iniset $KEYSTONE_CONF resource admin_project_name admin
-
     if [[ "$KEYSTONE_SECURITY_COMPLIANCE_ENABLED" = True ]]; then
         iniset $KEYSTONE_CONF security_compliance lockout_failure_attempts $KEYSTONE_LOCKOUT_FAILURE_ATTEMPTS
         iniset $KEYSTONE_CONF security_compliance lockout_duration $KEYSTONE_LOCKOUT_DURATION
@@ -413,6 +382,7 @@
     local section=${3:-keystone_authtoken}
 
     iniset $conf_file $section auth_type password
+    iniset $conf_file $section interface public
     iniset $conf_file $section auth_url $KEYSTONE_SERVICE_URI
     iniset $conf_file $section username $admin_user
     iniset $conf_file $section password $SERVICE_PASSWORD
@@ -509,14 +479,6 @@
 
 # start_keystone() - Start running processes
 function start_keystone {
-    # Get right service port for testing
-    local service_port=$KEYSTONE_SERVICE_PORT
-    local auth_protocol=$KEYSTONE_AUTH_PROTOCOL
-    if is_service_enabled tls-proxy; then
-        service_port=$KEYSTONE_SERVICE_PORT_INT
-        auth_protocol="http"
-    fi
-
     if [ "$KEYSTONE_DEPLOY" == "mod_wsgi" ]; then
         enable_apache_site keystone
         restart_apache_server
@@ -525,23 +487,13 @@
     fi
 
     echo "Waiting for keystone to start..."
-    # Check that the keystone service is running. Even if the tls tunnel
-    # should be enabled, make sure the internal port is checked using
-    # unencryted traffic at this point.
-    # If running in Apache, use the path rather than port.
-
+    # Check that the keystone service is running.
     local service_uri=$auth_protocol://$KEYSTONE_SERVICE_HOST/identity/v$IDENTITY_API_VERSION/
 
     if ! wait_for_service $SERVICE_TIMEOUT $service_uri; then
         die $LINENO "keystone did not start"
     fi
 
-    # Start proxies if enabled
-    if is_service_enabled tls-proxy; then
-        start_tls_proxy keystone-service '*' $KEYSTONE_SERVICE_PORT $KEYSTONE_SERVICE_HOST $KEYSTONE_SERVICE_PORT_INT
-        start_tls_proxy keystone-auth '*' $KEYSTONE_AUTH_PORT $KEYSTONE_AUTH_HOST $KEYSTONE_AUTH_PORT_INT
-    fi
-
     # (re)start memcached to make sure we have a clean memcache.
     restart_service memcached
 }
@@ -560,12 +512,9 @@
 # This function uses the following GLOBAL variables:
 # - ``KEYSTONE_BIN_DIR``
 # - ``ADMIN_PASSWORD``
-# - ``IDENTITY_API_VERSION``
 # - ``KEYSTONE_AUTH_URI``
 # - ``REGION_NAME``
-# - ``KEYSTONE_SERVICE_PROTOCOL``
-# - ``KEYSTONE_SERVICE_HOST``
-# - ``KEYSTONE_SERVICE_PORT``
+# - ``KEYSTONE_SERVICE_URI``
 function bootstrap_keystone {
     $KEYSTONE_BIN_DIR/keystone-manage bootstrap \
         --bootstrap-username admin \
diff --git a/lib/neutron-legacy b/lib/neutron-legacy
index bb1536a..59649ef 100644
--- a/lib/neutron-legacy
+++ b/lib/neutron-legacy
@@ -372,7 +372,7 @@
 function create_nova_conf_neutron {
     local conf=${1:-$NOVA_CONF}
     iniset $conf neutron auth_type "password"
-    iniset $conf neutron auth_url "$KEYSTONE_AUTH_URI"
+    iniset $conf neutron auth_url "$KEYSTONE_SERVICE_URI"
     iniset $conf neutron username "$Q_ADMIN_USERNAME"
     iniset $conf neutron password "$SERVICE_PASSWORD"
     iniset $conf neutron user_domain_name "$SERVICE_DOMAIN_NAME"
@@ -622,7 +622,7 @@
             IP_UP="sudo ip link set $to_intf up"
             if [[ "$af" == "inet" ]]; then
                 IP=$(echo $IP_BRD | awk '{ print $1; exit }' | grep -o -E '(.*)/' | cut -d "/" -f1)
-                ARP_CMD="sudo arping -A -c 3 -w 4.5 -I $to_intf $IP "
+                ARP_CMD="sudo arping -A -c 3 -w 5 -I $to_intf $IP "
             fi
         fi
 
diff --git a/lib/nova_plugins/hypervisor-ironic b/lib/nova_plugins/hypervisor-ironic
index b147c43..bda6ef6 100644
--- a/lib/nova_plugins/hypervisor-ironic
+++ b/lib/nova_plugins/hypervisor-ironic
@@ -46,7 +46,7 @@
     iniset $NOVA_CONF ironic auth_type password
     iniset $NOVA_CONF ironic username admin
     iniset $NOVA_CONF ironic password $ADMIN_PASSWORD
-    iniset $NOVA_CONF ironic auth_url $KEYSTONE_AUTH_URI
+    iniset $NOVA_CONF ironic auth_url $KEYSTONE_SERVICE_URI
     iniset $NOVA_CONF ironic project_domain_id default
     iniset $NOVA_CONF ironic user_domain_id default
     iniset $NOVA_CONF ironic project_name demo
diff --git a/lib/swift b/lib/swift
index 3c121ca..a981dfc 100644
--- a/lib/swift
+++ b/lib/swift
@@ -527,7 +527,7 @@
         else
             iniset ${testfile} func_test auth_port 80
         fi
-        iniset ${testfile} func_test auth_uri ${KEYSTONE_AUTH_URI}
+        iniset ${testfile} func_test auth_uri ${KEYSTONE_SERVICE_URI}
         if [[ "$auth_vers" == "3" ]]; then
             iniset ${testfile} func_test auth_prefix /identity/v3/
         else
diff --git a/lib/tls b/lib/tls
index d05536b..baafb59 100644
--- a/lib/tls
+++ b/lib/tls
@@ -227,13 +227,7 @@
 function init_cert {
     if [[ ! -r $DEVSTACK_CERT ]]; then
         if [[ -n "$TLS_IP" ]]; then
-            if python3_enabled; then
-                TLS_IP="IP:$TLS_IP"
-            else
-                # Lie to let incomplete match routines work with python2
-                # see https://bugs.python.org/issue23239
-                TLS_IP="DNS:$TLS_IP,IP:$TLS_IP"
-            fi
+            TLS_IP="IP:$TLS_IP"
             if [[ -n "$HOST_IPV6" ]]; then
                 TLS_IP="$TLS_IP,IP:$HOST_IPV6"
             fi
diff --git a/openrc b/openrc
index 99d3351..28f388b 100644
--- a/openrc
+++ b/openrc
@@ -86,10 +86,10 @@
 #
 
 # If you don't have a working .stackenv, this is the backup position
-KEYSTONE_BACKUP=$SERVICE_PROTOCOL://$SERVICE_HOST:5000
-KEYSTONE_AUTH_URI=${KEYSTONE_AUTH_URI:-$KEYSTONE_BACKUP}
+KEYSTONE_BACKUP=$SERVICE_PROTOCOL://$SERVICE_HOST/identity
+KEYSTONE_SERVICE_URI=${KEYSTONE_SERVICE_URI:-$KEYSTONE_BACKUP}
 
-export OS_AUTH_URL=${OS_AUTH_URL:-$KEYSTONE_AUTH_URI}
+export OS_AUTH_URL=${OS_AUTH_URL:-$KEYSTONE_SERVICE_URI}
 
 # Currently, in order to use openstackclient with Identity API v3,
 # we need to set the domain which the user and project belong to.
diff --git a/stack.sh b/stack.sh
index 80c6d4d..37e7518 100755
--- a/stack.sh
+++ b/stack.sh
@@ -221,7 +221,7 @@
 
 # Warn users who aren't on an explicitly supported distro, but allow them to
 # override check and attempt installation with ``FORCE=yes ./stack``
-if [[ ! ${DISTRO} =~ (bionic|stretch|jessie|f30|f31|opensuse-15.0|opensuse-15.1|opensuse-tumbleweed|rhel8) ]]; then
+if [[ ! ${DISTRO} =~ (bionic|focal|f30|f31|opensuse-15.0|opensuse-15.1|opensuse-tumbleweed|rhel8) ]]; then
     echo "WARNING: this script has not been tested on $DISTRO"
     if [[ "$FORCE" != "yes" ]]; then
         die $LINENO "If you wish to run this script anyway run with FORCE=yes"
@@ -1053,7 +1053,7 @@
 
 # Set up password auth credentials now that Keystone is bootstrapped
 export OS_IDENTITY_API_VERSION=3
-export OS_AUTH_URL=$KEYSTONE_AUTH_URI
+export OS_AUTH_URL=$KEYSTONE_SERVICE_URI
 export OS_USERNAME=admin
 export OS_USER_DOMAIN_ID=default
 export OS_PASSWORD=$ADMIN_PASSWORD
diff --git a/stackrc b/stackrc
index 07c4c4b..4ffd537 100644
--- a/stackrc
+++ b/stackrc
@@ -134,25 +134,17 @@
 fi
 
 # Control whether Python 3 should be used at all.
-export USE_PYTHON3=$(trueorfalse True USE_PYTHON3)
+# TODO(frickler): Drop this when all consumers are fixed
+export USE_PYTHON3=True
 
-# When Python 3 is supported by an application, adding the specific
-# version of Python 3 to this variable will install the app using that
-# version of the interpreter instead of 2.7.
+# Adding the specific version of Python 3 to this variable will install
+# the app using that version of the interpreter instead of just 3.
 _DEFAULT_PYTHON3_VERSION="$(_get_python_version python3)"
 export PYTHON3_VERSION=${PYTHON3_VERSION:-${_DEFAULT_PYTHON3_VERSION:-3}}
 
-# Just to be more explicit on the Python 2 version to use.
-_DEFAULT_PYTHON2_VERSION="$(_get_python_version python2)"
-export PYTHON2_VERSION=${PYTHON2_VERSION:-${_DEFAULT_PYTHON2_VERSION:-2.7}}
-
 # Create a virtualenv with this
-if [[ ${USE_PYTHON3} == True ]]; then
-    # Use the built-in venv to avoid more dependencies
-    export VIRTUALENV_CMD="python3 -m venv"
-else
-    export VIRTUALENV_CMD="virtualenv "
-fi
+# Use the built-in venv to avoid more dependencies
+export VIRTUALENV_CMD="python3 -m venv"
 
 # Default for log coloring is based on interactive-or-not.
 # Baseline assumption is that non-interactive invocations are for CI,
@@ -281,10 +273,6 @@
 NEUTRON_REPO=${NEUTRON_REPO:-${GIT_BASE}/openstack/neutron.git}
 NEUTRON_BRANCH=${NEUTRON_BRANCH:-$TARGET_BRANCH}
 
-# neutron fwaas service
-NEUTRON_FWAAS_REPO=${NEUTRON_FWAAS_REPO:-${GIT_BASE}/openstack/neutron-fwaas.git}
-NEUTRON_FWAAS_BRANCH=${NEUTRON_FWAAS_BRANCH:-$TARGET_BRANCH}
-
 # compute service
 NOVA_REPO=${NOVA_REPO:-${GIT_BASE}/openstack/nova.git}
 NOVA_BRANCH=${NOVA_BRANCH:-$TARGET_BRANCH}
diff --git a/tools/create_userrc.sh b/tools/create_userrc.sh
index f4a4edc..c7bea4a 100755
--- a/tools/create_userrc.sh
+++ b/tools/create_userrc.sh
@@ -152,7 +152,7 @@
 fi
 
 if [ -z "$OS_AUTH_URL" ]; then
-    export OS_AUTH_URL=http://localhost:5000/v3/
+    export OS_AUTH_URL=http://localhost/identity/v3/
 fi
 
 if [ -z "$OS_USER_DOMAIN_ID" -a -z "$OS_USER_DOMAIN_NAME" ]; then
diff --git a/tools/fixup_stuff.sh b/tools/fixup_stuff.sh
index e140929..2ac8a47 100755
--- a/tools/fixup_stuff.sh
+++ b/tools/fixup_stuff.sh
@@ -26,39 +26,6 @@
     FILES=$TOP_DIR/files
 fi
 
-# Keystone Port Reservation
-# -------------------------
-# Reserve and prevent ``KEYSTONE_AUTH_PORT`` and ``KEYSTONE_AUTH_PORT_INT`` from
-# being used as ephemeral ports by the system. The default(s) are 35357 and
-# 35358 which are in the Linux defined ephemeral port range (in disagreement
-# with the IANA ephemeral port range). This is a workaround for bug #1253482
-# where Keystone will try and bind to the port and the port will already be
-# in use as an ephemeral port by another process. This places an explicit
-# exception into the Kernel for the Keystone AUTH ports.
-function fixup_keystone {
-    keystone_ports=${KEYSTONE_AUTH_PORT:-35357},${KEYSTONE_AUTH_PORT_INT:-35358}
-
-    # Only do the reserved ports when available, on some system (like containers)
-    # where it's not exposed we are almost pretty sure these ports would be
-    # exclusive for our DevStack.
-    if sysctl net.ipv4.ip_local_reserved_ports >/dev/null 2>&1; then
-        # Get any currently reserved ports, strip off leading whitespace
-        reserved_ports=$(sysctl net.ipv4.ip_local_reserved_ports | awk -F'=' '{print $2;}' | sed 's/^ //')
-
-        if [[ -z "${reserved_ports}" ]]; then
-            # If there are no currently reserved ports, reserve the keystone ports
-            sudo sysctl -w net.ipv4.ip_local_reserved_ports=${keystone_ports}
-        else
-            # If there are currently reserved ports, keep those and also reserve the
-            # Keystone specific ports. Duplicate reservations are merged into a single
-            # reservation (or range) automatically by the kernel.
-            sudo sysctl -w net.ipv4.ip_local_reserved_ports=${keystone_ports},${reserved_ports}
-        fi
-    else
-        echo_summary "WARNING: unable to reserve keystone ports"
-    fi
-}
-
 # Ubuntu Repositories
 #--------------------
 # Enable universe for bionic since it is missing when installing from ISO.
@@ -208,7 +175,6 @@
 }
 
 function fixup_all {
-    fixup_keystone
     fixup_ubuntu
     fixup_fedora
     fixup_suse
diff --git a/tools/install_pip.sh b/tools/install_pip.sh
index 5eb538c..f3fd1e2 100755
--- a/tools/install_pip.sh
+++ b/tools/install_pip.sh
@@ -5,7 +5,7 @@
 # Update pip and friends to a known common version
 
 # Assumptions:
-# - if USE_PYTHON3=True, PYTHON3_VERSION refers to a version already installed
+# - PYTHON3_VERSION refers to a version already installed
 
 set -o errexit
 
@@ -53,6 +53,8 @@
     else
         echo "pip: Not Installed"
     fi
+    # Show python3 module version
+    python${PYTHON3_VERSION} -m pip --version
 }
 
 
@@ -90,9 +92,6 @@
         touch $LOCAL_PIP.downloaded
     fi
     sudo -H -E python${PYTHON3_VERSION} $LOCAL_PIP
-    if ! python3_enabled; then
-        sudo -H -E python $LOCAL_PIP
-    fi
 }
 
 
@@ -125,7 +124,14 @@
 # Show starting versions
 get_versions
 
-# Do pip
+if [[ -n $PYPI_ALTERNATIVE_URL ]]; then
+    configure_pypi_alternative_url
+fi
+
+# Just use system pkgs on Focal
+if [[ "$DISTRO" == focal ]]; then
+    exit 0
+fi
 
 # Eradicate any and all system packages
 
@@ -133,9 +139,6 @@
 # results in a nonfunctional system. pip on fedora installs to /usr so pip
 # can safely override the system pip for all versions of fedora
 if ! is_fedora  && ! is_suse; then
-    if is_package_installed python-pip ; then
-        uninstall_package python-pip
-    fi
     if is_package_installed python3-pip ; then
         uninstall_package python3-pip
     fi
@@ -143,10 +146,6 @@
 
 install_get_pip
 
-if [[ -n $PYPI_ALTERNATIVE_URL ]]; then
-    configure_pypi_alternative_url
-fi
-
 set -x
 
 # Note setuptools is part of requirements.txt and we want to make sure
diff --git a/unstack.sh b/unstack.sh
index ccea0ef..276111e 100755
--- a/unstack.sh
+++ b/unstack.sh
@@ -99,6 +99,7 @@
 
 if is_service_enabled nova; then
     stop_nova
+    cleanup_nova
 fi
 
 if is_service_enabled placement; then