Merge "remove external_network_bridge option"
diff --git a/.zuul.yaml b/.zuul.yaml
index 9d73bed..6682142 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -9,6 +9,16 @@
           - controller
 
 - nodeset:
+    name: openstack-single-node-bionic
+    nodes:
+      - name: controller
+        label: ubuntu-bionic
+    groups:
+      - name: tempest
+        nodes:
+          - controller
+
+- nodeset:
     name: devstack-single-node-centos-7
     nodes:
       - name: controller
@@ -19,10 +29,10 @@
           - controller
 
 - nodeset:
-    name: devstack-single-node-opensuse-423
+    name: devstack-single-node-opensuse-150
     nodes:
       - name: controller
-        label: opensuse-423
+        label: opensuse-150
     groups:
       - name: tempest
         nodes:
@@ -376,6 +386,19 @@
           VNCSERVER_PROXYCLIENT_ADDRESS: $HOST_IP
 
 - job:
+    name: devstack-ipv6
+    parent: devstack
+    description: |
+      Devstack single node job for integration gate with IPv6.
+    vars:
+      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
     parent: devstack
     nodeset: openstack-two-node
@@ -395,10 +418,10 @@
     voting: false
 
 - job:
-    name: devstack-platform-opensuse-423
+    name: devstack-platform-opensuse-150
     parent: tempest-full
-    description: openSUSE 43.2 platform test
-    nodeset: devstack-single-node-opensuse-423
+    description: openSUSE 15.0 platform test
+    nodeset: devstack-single-node-opensuse-150
     voting: false
 
 - job:
@@ -486,8 +509,10 @@
     check:
       jobs:
         - devstack
+        - devstack-ipv6:
+            voting: false
         - devstack-platform-centos-7
-        - devstack-platform-opensuse-423
+        - devstack-platform-opensuse-150
         - devstack-platform-opensuse-tumbleweed
         - devstack-platform-fedora-latest
         - devstack-multinode
@@ -587,7 +612,7 @@
             irrelevant-files:
               - ^.*\.rst$
               - ^doc/.*$
-        - legacy-tempest-dsvm-neutron-pg-full:
+        - tempest-pg-full:
             irrelevant-files:
               - ^.*\.rst$
               - ^doc/.*$
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 46e50df..022e6ba 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -446,6 +446,16 @@
 
      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
 --------------------------
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 2ff4ff0..fcf1e82 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -39,8 +39,9 @@
 -------------
 
 Start with a clean and minimal install of a Linux system. Devstack
-attempts to support Ubuntu 16.04/17.04, Fedora 24/25, CentOS/RHEL 7,
-as well as Debian and OpenSUSE.
+attempts to support the two latest LTS releases of Ubuntu, the
+latest/current Fedora version, CentOS/RHEL 7, as well as Debian and
+OpenSUSE.
 
 If you do not have a preference, Ubuntu 16.04 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 f0c6238..b02061e 100644
--- a/doc/source/plugin-registry.rst
+++ b/doc/source/plugin-registry.rst
@@ -27,7 +27,6 @@
 almanach                               `git://git.openstack.org/openstack/almanach <https://git.openstack.org/cgit/openstack/almanach>`__
 aodh                                   `git://git.openstack.org/openstack/aodh <https://git.openstack.org/cgit/openstack/aodh>`__
 apmec                                  `git://git.openstack.org/openstack/apmec <https://git.openstack.org/cgit/openstack/apmec>`__
-astara                                 `git://git.openstack.org/openstack/astara <https://git.openstack.org/cgit/openstack/astara>`__
 barbican                               `git://git.openstack.org/openstack/barbican <https://git.openstack.org/cgit/openstack/barbican>`__
 bilean                                 `git://git.openstack.org/openstack/bilean <https://git.openstack.org/cgit/openstack/bilean>`__
 blazar                                 `git://git.openstack.org/openstack/blazar <https://git.openstack.org/cgit/openstack/blazar>`__
@@ -62,10 +61,10 @@
 freezer-api                            `git://git.openstack.org/openstack/freezer-api <https://git.openstack.org/cgit/openstack/freezer-api>`__
 freezer-tempest-plugin                 `git://git.openstack.org/openstack/freezer-tempest-plugin <https://git.openstack.org/cgit/openstack/freezer-tempest-plugin>`__
 freezer-web-ui                         `git://git.openstack.org/openstack/freezer-web-ui <https://git.openstack.org/cgit/openstack/freezer-web-ui>`__
-fuxi                                   `git://git.openstack.org/openstack/fuxi <https://git.openstack.org/cgit/openstack/fuxi>`__
 gce-api                                `git://git.openstack.org/openstack/gce-api <https://git.openstack.org/cgit/openstack/gce-api>`__
 glare                                  `git://git.openstack.org/openstack/glare <https://git.openstack.org/cgit/openstack/glare>`__
 group-based-policy                     `git://git.openstack.org/openstack/group-based-policy <https://git.openstack.org/cgit/openstack/group-based-policy>`__
+gyan                                   `git://git.openstack.org/openstack/gyan <https://git.openstack.org/cgit/openstack/gyan>`__
 heat                                   `git://git.openstack.org/openstack/heat <https://git.openstack.org/cgit/openstack/heat>`__
 heat-dashboard                         `git://git.openstack.org/openstack/heat-dashboard <https://git.openstack.org/cgit/openstack/heat-dashboard>`__
 horizon-mellanox                       `git://git.openstack.org/openstack/horizon-mellanox <https://git.openstack.org/cgit/openstack/horizon-mellanox>`__
@@ -172,6 +171,8 @@
 stackube                               `git://git.openstack.org/openstack/stackube <https://git.openstack.org/cgit/openstack/stackube>`__
 storlets                               `git://git.openstack.org/openstack/storlets <https://git.openstack.org/cgit/openstack/storlets>`__
 stx-config                             `git://git.openstack.org/openstack/stx-config <https://git.openstack.org/cgit/openstack/stx-config>`__
+stx-fault                              `git://git.openstack.org/openstack/stx-fault <https://git.openstack.org/cgit/openstack/stx-fault>`__
+stx-update                             `git://git.openstack.org/openstack/stx-update <https://git.openstack.org/cgit/openstack/stx-update>`__
 tacker                                 `git://git.openstack.org/openstack/tacker <https://git.openstack.org/cgit/openstack/tacker>`__
 tap-as-a-service                       `git://git.openstack.org/openstack/tap-as-a-service <https://git.openstack.org/cgit/openstack/tap-as-a-service>`__
 tap-as-a-service-dashboard             `git://git.openstack.org/openstack/tap-as-a-service-dashboard <https://git.openstack.org/cgit/openstack/tap-as-a-service-dashboard>`__
diff --git a/files/apache-horizon.template b/files/apache-horizon.template
index bfd7567..efcfc03 100644
--- a/files/apache-horizon.template
+++ b/files/apache-horizon.template
@@ -1,5 +1,5 @@
 <VirtualHost *:80>
-    WSGIScriptAlias %WEBROOT% %HORIZON_DIR%/openstack_dashboard/wsgi/django.wsgi
+    WSGIScriptAlias %WEBROOT% %HORIZON_DIR%/openstack_dashboard/wsgi.py
     WSGIDaemonProcess horizon user=%USER% group=%GROUP% processes=3 threads=10 home=%HORIZON_DIR% display-name=%{GROUP}
     WSGIApplicationGroup %{GLOBAL}
 
diff --git a/functions b/functions
index f63595d..051c816 100644
--- a/functions
+++ b/functions
@@ -282,7 +282,6 @@
             image create \
             "$image_name" --public \
             --container-format=bare --disk-format=ploop \
-            --property hypervisor_type=vz \
             --property vm_mode=$vm_mode < "${image}"
         return
     fi
diff --git a/functions-common b/functions-common
index fae936a..af95bfb 100644
--- a/functions-common
+++ b/functions-common
@@ -228,9 +228,9 @@
     xtrace=$(set +o | grep xtrace)
     set +o xtrace
     local msg="[ERROR] ${BASH_SOURCE[2]}:$1 $2"
-    echo $msg 1>&2;
+    echo "$msg" 1>&2;
     if [[ -n ${LOGDIR} ]]; then
-        echo $msg >> "${LOGDIR}/error.log"
+        echo "$msg" >> "${LOGDIR}/error.log"
     fi
     $xtrace
     return $exitcode
@@ -283,7 +283,7 @@
     xtrace=$(set +o | grep xtrace)
     set +o xtrace
     local msg="[WARNING] ${BASH_SOURCE[2]}:$1 $2"
-    echo $msg
+    echo "$msg"
     $xtrace
     return $exitcode
 }
@@ -374,8 +374,10 @@
     elif [[ "$os_VENDOR" =~ (openSUSE) ]]; then
         DISTRO="opensuse-$os_RELEASE"
         # Tumbleweed uses "n/a" as a codename, and the release is a datestring
-        # like 20180218, so not very useful.
-        [ "$os_CODENAME" = "n/a" ] && DISTRO="opensuse-tumbleweed"
+        # like 20180218, so not very useful. Leap however uses a release
+        # with a "dot", so for example 15.0
+        [ "$os_CODENAME" = "n/a" -a "$os_RELEASE" = "${os_RELEASE/\./}" ] && \
+            DISTRO="opensuse-tumbleweed"
     elif [[ "$os_VENDOR" =~ (SUSE LINUX) ]]; then
         # just use major release
         DISTRO="sle${os_RELEASE%.*}"
@@ -1376,7 +1378,7 @@
     [[ "$(id -u)" = "0" ]] && sudo="env"
     $sudo http_proxy="${http_proxy:-}" https_proxy="${https_proxy:-}" \
         no_proxy="${no_proxy:-}" \
-        zypper --non-interactive install --auto-agree-with-licenses "$@"
+        zypper --non-interactive install --auto-agree-with-licenses --no-recommends "$@"
 }
 
 function write_user_unit_file {
@@ -1439,24 +1441,24 @@
     # do some sanity checks on $cmd to see things we don't expect to work
 
     if [[ "$cmd" =~ "sudo" ]]; then
-        local msg=<<EOF
+        read -r -d '' msg << EOF || true  # read returns 1 for EOF, but it is ok here
 You are trying to use run_process with sudo, this is not going to work under systemd.
 
-If you need to run a service as a user other than $STACK_USER call it with:
+If you need to run a service as a user other than \$STACK_USER call it with:
 
    run_process \$name \$cmd \$group \$user
 EOF
-        die $LINENO $msg
+        die $LINENO "$msg"
     fi
 
     if [[ ! "$cmd" =~ ^/ ]]; then
-        local msg=<<EOF
+        read -r -d '' msg << EOF || true  # read returns 1 for EOF, but it is ok here
 The cmd="$cmd" does not start with an absolute path. It will fail to
 start under systemd.
 
 Please update your run_process stanza to have an absolute path.
 EOF
-        die $LINENO $msg
+        die $LINENO "$msg"
     fi
 
 }
diff --git a/inc/python b/inc/python
index 96be107..d8b8169 100644
--- a/inc/python
+++ b/inc/python
@@ -49,7 +49,7 @@
     fi
     $xtrace
 
-    if python3_enabled && [ "$os_VENDOR" = "Fedora" -a $os_RELEASE -gt 26 ]; then
+    if python3_enabled && [[ "$os_VENDOR" == "Fedora" && $os_RELEASE -gt 26 ]]; then
         # Default Python 3 install prefix changed to /usr/local in Fedora 27:
         # https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe
         echo "/usr/local/bin"
diff --git a/lib/cinder b/lib/cinder
index 664f423..76bf928 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -96,9 +96,9 @@
 # https://bugs.launchpad.net/cinder/+bug/1180976
 CINDER_PERIODIC_INTERVAL=${CINDER_PERIODIC_INTERVAL:-60}
 
-# Centos7 switched to using LIO and that's all that's supported,
-# although the tgt bits are in EPEL we don't want that for CI
-if is_fedora; then
+# Centos7 and OpenSUSE switched to using LIO and that's all that's supported,
+# although the tgt bits are in EPEL and OpenSUSE we don't want that for CI
+if is_fedora || is_suse; then
     CINDER_ISCSI_HELPER=${CINDER_ISCSI_HELPER:-lioadm}
     if [[ ${CINDER_ISCSI_HELPER} != "lioadm" ]]; then
         die "lioadm is the only valid Cinder target_helper config on this platform"
diff --git a/lib/cinder_backends/ceph b/lib/cinder_backends/ceph
index 00a0bb3..33c9706 100644
--- a/lib/cinder_backends/ceph
+++ b/lib/cinder_backends/ceph
@@ -65,7 +65,7 @@
         sudo ceph -c ${CEPH_CONF_FILE} auth get-or-create client.${CINDER_BAK_CEPH_USER} mon "allow r" osd "allow class-read object_prefix rbd_children, allow rwx pool=${CINDER_BAK_CEPH_POOL}, allow rwx pool=${CINDER_CEPH_POOL}" | sudo tee ${CEPH_CONF_DIR}/ceph.client.${CINDER_BAK_CEPH_USER}.keyring
         sudo chown $(whoami):$(whoami) ${CEPH_CONF_DIR}/ceph.client.${CINDER_BAK_CEPH_USER}.keyring
 
-        iniset $CINDER_CONF DEFAULT backup_driver "cinder.backup.drivers.ceph"
+        iniset $CINDER_CONF DEFAULT backup_driver "cinder.backup.drivers.ceph.CephBackupDriver"
         iniset $CINDER_CONF DEFAULT backup_ceph_conf "$CEPH_CONF_FILE"
         iniset $CINDER_CONF DEFAULT backup_ceph_pool "$CINDER_BAK_CEPH_POOL"
         iniset $CINDER_CONF DEFAULT backup_ceph_user "$CINDER_BAK_CEPH_USER"
diff --git a/lib/databases/mysql b/lib/databases/mysql
index cf61056..ac0c083 100644
--- a/lib/databases/mysql
+++ b/lib/databases/mysql
@@ -16,7 +16,7 @@
 register_database mysql
 
 MYSQL_SERVICE_NAME=mysql
-if is_fedora && ! is_oraclelinux; then
+if is_suse || is_fedora && ! is_oraclelinux; then
     MYSQL_SERVICE_NAME=mariadb
 fi
 
diff --git a/lib/neutron_plugins/bigswitch_floodlight b/lib/neutron_plugins/bigswitch_floodlight
index 52c6ad5..d3f5bd5 100644
--- a/lib/neutron_plugins/bigswitch_floodlight
+++ b/lib/neutron_plugins/bigswitch_floodlight
@@ -1,6 +1,6 @@
 #!/bin/bash
 #
-# Neuton Big Switch/FloodLight plugin
+# Neutron Big Switch/FloodLight plugin
 # ------------------------------------
 
 # Save trace setting
diff --git a/lib/neutron_plugins/services/l3 b/lib/neutron_plugins/services/l3
index 9be32b7..ec289f6 100644
--- a/lib/neutron_plugins/services/l3
+++ b/lib/neutron_plugins/services/l3
@@ -103,7 +103,7 @@
 default_v4_route_devs=$(ip -4 route | grep ^default | awk '{print $5}')
 die_if_not_set $LINENO default_v4_route_devs "Failure retrieving default IPv4 route devices"
 
-default_v6_route_devs=$(ip -6 route | grep ^default | awk '{print $5}')
+default_v6_route_devs=$(ip -6 route list match default table all | grep via | awk '{print $5}')
 
 function _determine_config_l3 {
     local opts="--config-file $NEUTRON_CONF --config-file $Q_L3_CONF_FILE"
@@ -395,6 +395,10 @@
 
     # 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.
         # This is needed for neutron-based devstack clouds to work in
         # IPv6-only clouds in the gate. Please do not remove this without
@@ -405,8 +409,6 @@
             # 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/lib/nova b/lib/nova
index 5e157c5..d1d0b3c 100644
--- a/lib/nova
+++ b/lib/nova
@@ -303,17 +303,6 @@
             # to simulate multiple systems.
             if [[ "$LIBVIRT_TYPE" == "lxc" ]]; then
                 if is_ubuntu; then
-                    if [[ ! "$DISTRO" > natty ]]; then
-                        local cgline="none /cgroup cgroup cpuacct,memory,devices,cpu,freezer,blkio 0 0"
-                        sudo mkdir -p /cgroup
-                        if ! grep -q cgroup /etc/fstab; then
-                            echo "$cgline" | sudo tee -a /etc/fstab
-                        fi
-                        if ! mount -n | grep -q cgroup; then
-                            sudo mount /cgroup
-                        fi
-                    fi
-
                     # enable nbd for lxc unless you're using an lvm backend
                     # otherwise you can't boot instances
                     if [[ "$NOVA_BACKEND" != "LVM" ]]; then
@@ -922,6 +911,9 @@
         # RPC, we also disable track_instance_changes.
         iniset $NOVA_CPU_CONF filter_scheduler track_instance_changes False
         iniset_rpc_backend nova $NOVA_CPU_CONF DEFAULT "nova_cell${NOVA_CPU_CELL}"
+        # Make sure we nuke any database config
+        inidelete $NOVA_CPU_CONF database connection
+        inidelete $NOVA_CPU_CONF api_database connection
     fi
 
     # Console proxies were configured earlier in create_nova_conf. Now that the
diff --git a/lib/tempest b/lib/tempest
index 3fefa5b..fba8826 100644
--- a/lib/tempest
+++ b/lib/tempest
@@ -456,9 +456,6 @@
         TEMPEST_EXTEND_ATTACHED_VOLUME=${TEMPEST_EXTEND_ATTACHED_VOLUME:-True}
     fi
     iniset $TEMPEST_CONFIG volume-feature-enabled extend_attached_volume $(trueorfalse False TEMPEST_EXTEND_ATTACHED_VOLUME)
-    # TODO(ameade): Remove the api_v3 flag when Mitaka and Liberty are end of life.
-    iniset $TEMPEST_CONFIG volume-feature-enabled api_v3 True
-    iniset $TEMPEST_CONFIG volume-feature-enabled api_v1 $(trueorfalse False TEMPEST_VOLUME_API_V1)
     local tempest_volume_min_microversion=${TEMPEST_VOLUME_MIN_MICROVERSION:-None}
     local tempest_volume_max_microversion=${TEMPEST_VOLUME_MAX_MICROVERSION:-"latest"}
     # Reset microversions to None where v2 is running which does not support microversion.
diff --git a/lib/tls b/lib/tls
index e3ed3cc..217f40e 100644
--- a/lib/tls
+++ b/lib/tls
@@ -227,9 +227,13 @@
 function init_cert {
     if [[ ! -r $DEVSTACK_CERT ]]; then
         if [[ -n "$TLS_IP" ]]; then
-            # Lie to let incomplete match routines work
-            # see https://bugs.python.org/issue23239
-            TLS_IP="DNS:$TLS_IP,IP:$TLS_IP"
+            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
         fi
         make_cert $INT_CA_DIR $DEVSTACK_CERT_NAME $DEVSTACK_HOSTNAME "$TLS_IP"
 
diff --git a/stack.sh b/stack.sh
index 56e00bf..be3c4be 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} =~ (xenial|artful|bionic|stretch|jessie|f27|f28|opensuse-42.3|opensuse-tumbleweed|rhel7) ]]; then
+if [[ ! ${DISTRO} =~ (xenial|artful|bionic|stretch|jessie|f27|f28|opensuse-42.3|opensuse-15.0|opensuse-tumbleweed|rhel7) ]]; 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"
@@ -1137,6 +1137,7 @@
     echo_summary "Configuring Neutron"
 
     configure_neutron
+
     # Run init_neutron only on the node hosting the Neutron API server
     if is_service_enabled $DATABASE_BACKENDS && is_service_enabled neutron; then
         init_neutron
diff --git a/tools/fixup_stuff.sh b/tools/fixup_stuff.sh
index 9147932..a939e30 100755
--- a/tools/fixup_stuff.sh
+++ b/tools/fixup_stuff.sh
@@ -205,6 +205,19 @@
     fi
 }
 
+function fixup_suse {
+    if ! is_suse; then
+        return
+    fi
+
+    # Disable apparmor profiles in openSUSE distros
+    # to avoid issues with haproxy and dnsmasq
+    if [ -x /usr/sbin/aa-enabled ] && sudo /usr/sbin/aa-enabled -q; then
+        sudo systemctl disable apparmor
+        sudo /usr/sbin/aa-teardown
+    fi
+}
+
 # The version of pip(1.5.4) supported by python-virtualenv(1.11.4) has
 # connection issues under proxy so re-install the latest version using
 # pip. To avoid having pip's virtualenv overwritten by the distro's
@@ -239,5 +252,6 @@
     fixup_uca
     fixup_python_packages
     fixup_fedora
+    fixup_suse
     fixup_virtualenv
 }
diff --git a/tox.ini b/tox.ini
index 74436b0..f643fdb 100644
--- a/tox.ini
+++ b/tox.ini
@@ -8,6 +8,7 @@
 install_command = pip install {opts} {packages}
 
 [testenv:bashate]
+basepython = python3
 # if you want to test out some changes you have made to bashate
 # against devstack, just set BASHATE_INSTALL_PATH=/path/... to your
 # modified bashate tree
@@ -34,6 +35,7 @@
          -print0 | xargs -0 bashate -v -iE006 -eE005,E042"
 
 [testenv:docs]
+basepython = python3
 deps = -r{toxinidir}/doc/requirements.txt
 whitelist_externals = bash
 setenv =
@@ -42,5 +44,6 @@
   python setup.py build_sphinx
 
 [testenv:venv]
+basepython = python3
 deps = -r{toxinidir}/doc/requirements.txt
 commands = {posargs}