Merge "Set ksa retry conf options for n-cpu [ironic]"
diff --git a/HACKING.rst b/HACKING.rst
index f695106..f0bb269 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -189,7 +189,7 @@
 list below is not complete for what bashate checks, nor is it all checked
 by bashate.  So many lines of code, so little time.
 
-.. _bashate: https://pypi.python.org/pypi/bashate
+.. _bashate: https://pypi.org/project/bashate/
 
 Whitespace Rules
 ----------------
diff --git a/doc/requirements.txt b/doc/requirements.txt
index f65e9df..fffb83d 100644
--- a/doc/requirements.txt
+++ b/doc/requirements.txt
@@ -3,7 +3,7 @@
 Pygments
 docutils
 sphinx>=1.6.2
-openstackdocstheme>=1.11.0
+openstackdocstheme>=1.20.0
 nwdiag
 blockdiag
 sphinxcontrib-blockdiag
diff --git a/doc/source/conf.py b/doc/source/conf.py
index e9708fa..9059f8c 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -11,9 +11,6 @@
 # All configuration values have a default; values that are commented out
 # serve to show the default.
 
-import sys
-import os
-
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
@@ -26,13 +23,16 @@
 
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = [ 'sphinx.ext.autodoc', 'zuul_sphinx', 'openstackdocstheme', 'sphinxcontrib.blockdiag', 'sphinxcontrib.nwdiag' ]
+extensions = [ 'sphinx.ext.autodoc',
+               'zuul_sphinx',
+               'openstackdocstheme',
+               'sphinxcontrib.blockdiag',
+               'sphinxcontrib.nwdiag' ]
 
 # openstackdocstheme options
 repository_name = 'openstack-dev/devstack'
 bug_project = 'devstack'
 bug_tag = ''
-html_last_updated_fmt = '%Y-%m-%d %H:%M'
 
 todo_include_todos = True
 
@@ -119,11 +119,6 @@
 # pixels large.
 #html_favicon = None
 
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-git_cmd = "git log --pretty=format:'%ad, commit %h' --date=local -n1"
-html_last_updated_fmt = os.popen(git_cmd).read()
-
 # If true, SmartyPants will be used to convert quotes and dashes to
 # typographically correct entities.
 #html_use_smartypants = True
@@ -167,17 +162,6 @@
 
 # -- Options for LaTeX output --------------------------------------------------
 
-latex_elements = {
-# The paper size ('letterpaper' or 'a4paper').
-#'papersize': 'letterpaper',
-
-# The font size ('10pt', '11pt' or '12pt').
-#'pointsize': '10pt',
-
-# Additional stuff for the LaTeX preamble.
-#'preamble': '',
-}
-
 # Grouping the document tree into LaTeX files. List of tuples
 # (source start file, target name, title, author, documentclass [howto/manual]).
 latex_documents = [
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 0105d5e..45f4ffe 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -259,6 +259,8 @@
 Logging
 -------
 
+.. _enable_logging:
+
 Enable Logging
 ~~~~~~~~~~~~~~
 
@@ -495,7 +497,7 @@
 default flavors instead.
 
 KVM on Power with QEMU 2.4 requires 512 MB to load the firmware -
-`QEMU 2.4 - PowerPC <http://wiki.qemu.org/ChangeLog/2.4>`__ so users
+`QEMU 2.4 - PowerPC <https://wiki.qemu.org/ChangeLog/2.4>`__ so users
 running instances on ppc64/ppc64le can choose one of the default
 created flavors as follows:
 
diff --git a/doc/source/guides/devstack-with-lbaas-v2.rst b/doc/source/guides/devstack-with-lbaas-v2.rst
index 1cd85b4..669a70d 100644
--- a/doc/source/guides/devstack-with-lbaas-v2.rst
+++ b/doc/source/guides/devstack-with-lbaas-v2.rst
@@ -39,7 +39,7 @@
     # If you are enabling horizon, include the octavia dashboard
     # enable_plugin octavia-dashboard https://opendev.org/openstack/octavia-dashboard.git
     # If you are enabling barbican for TLS offload in Octavia, include it here.
-    # enable_plugin barbican https://github.com/openstack/barbican.git
+    # enable_plugin barbican https://opendev.org/openstack/barbican
 
     # If you have python3 available:
     # USE_PYTHON3=True
diff --git a/doc/source/guides/nova.rst b/doc/source/guides/nova.rst
index 2271e23..5b42797 100644
--- a/doc/source/guides/nova.rst
+++ b/doc/source/guides/nova.rst
@@ -10,7 +10,7 @@
 ================
 
 In Juno, nova implemented a `spec
-<http://specs.openstack.org/openstack/nova-specs/specs/juno/implemented/serial-ports.html>`_
+<https://specs.openstack.org/openstack/nova-specs/specs/juno/implemented/serial-ports.html>`_
 to allow read/write access to the serial console of an instance via
 `nova-serialproxy
 <https://docs.openstack.org/nova/latest/cli/nova-serialproxy.html>`_.
@@ -63,7 +63,7 @@
 Enabling the service is enough to be functional for a single machine DevStack.
 
 These config options are defined in `nova.conf.serial_console
-<https://github.com/openstack/nova/blob/master/nova/conf/serial_console.py>`_.
+<https://opendev.org/openstack/nova/src/master/nova/conf/serial_console.py>`_.
 
 For more information on OpenStack configuration see the `OpenStack
 Compute Service Configuration Reference
diff --git a/doc/source/guides/single-vm.rst b/doc/source/guides/single-vm.rst
index 8ebf2a6..7dac18b 100644
--- a/doc/source/guides/single-vm.rst
+++ b/doc/source/guides/single-vm.rst
@@ -78,7 +78,7 @@
 to create a non-root user and run the ``start.sh`` script as that user.
 
 If you are using cloud-init and you have not
-`enabled custom logging <../configuration.html#enable-logging>`_ of the stack
+:ref:`enabled custom logging <enable_logging>` of the stack
 output, then the stack output can be found in
 ``/var/log/cloud-init-output.log`` by default.
 
diff --git a/doc/source/plugins.rst b/doc/source/plugins.rst
index 2484569..a18a786 100644
--- a/doc/source/plugins.rst
+++ b/doc/source/plugins.rst
@@ -332,6 +332,6 @@
 ========
 
 For additional inspiration on devstack plugins you can check out the
-`Plugin Registry <plugin-registry.html>`_.
+:doc:`Plugin Registry <plugin-registry>`.
 
 .. _service types authority: https://specs.openstack.org/openstack/service-types-authority/
diff --git a/doc/source/systemd.rst b/doc/source/systemd.rst
index 1bc9911..15b3f75 100644
--- a/doc/source/systemd.rst
+++ b/doc/source/systemd.rst
@@ -194,7 +194,7 @@
 
 See the `remote-pdb`_ home page for more options.
 
-.. _`remote-pdb`: https://pypi.python.org/pypi/remote-pdb
+.. _`remote-pdb`: https://pypi.org/project/remote-pdb/
 
 Known Issues
 ============
diff --git a/doc/source/zuul_ci_jobs_migration.rst b/doc/source/zuul_ci_jobs_migration.rst
index dbb7989..17e7e16 100644
--- a/doc/source/zuul_ci_jobs_migration.rst
+++ b/doc/source/zuul_ci_jobs_migration.rst
@@ -180,123 +180,147 @@
 devstack-gate defined a default value. In ansible jobs the default is either the
 value defined in the parent job, or the default from DevStack, if any.
 
-==============================================  ============= ==================
-DevStack gate flag                              Repo          New implementation
-==============================================  ============= ==================
-OVERRIDE_ZUUL_BRANCH                            zuul          override-checkout:
-                                                              [branch]
-                                                              in the job definition.
-DEVSTACK_GATE_NET_OVERLAY                       zuul-jobs     A bridge called
-                                                              br-infra is set up for
-                                                              all jobs that inherit
-                                                              from multinode with
-                                                              a dedicated `bridge role <https://docs.openstack.org/infra/zuul-jobs/roles.html#role-multi-node-bridge>`_.
-DEVSTACK_GATE_FEATURE_MATRIX                    devstack-gate ``test_matrix_features``
-                                                              variable of the
-                                                              test-matrix role in
-                                                              devstack-gate. This
-                                                              is a temporary
-                                                              solution, feature
-                                                              matrix will go away.
-                                                              In the future services
-                                                              will be defined in
-                                                              jobs only.
-DEVSTACK_CINDER_VOLUME_CLEAR                    devstack      *CINDER_VOLUME_CLEAR: true/false*
-                                                              in devstack_localrc
-                                                              in the job vars.
-DEVSTACK_GATE_NEUTRON                           devstack      True by default. To
-                                                              disable, disable all
-                                                              neutron services in
-                                                              devstack_services in
-                                                              the job definition.
-DEVSTACK_GATE_CONFIGDRIVE                       devstack      *FORCE_CONFIG_DRIVE: true/false*
-                                                              in devstack_localrc
-                                                              in the job vars.
-DEVSTACK_GATE_INSTALL_TESTONLY                  devstack      *INSTALL_TESTONLY_PACKAGES: true/false*
-                                                              in devstack_localrc
-                                                              in the job vars.
-DEVSTACK_GATE_VIRT_DRIVER                       devstack      *VIRT_DRIVER: [virt driver]*
-                                                              in devstack_localrc
-                                                              in the job vars.
-DEVSTACK_GATE_LIBVIRT_TYPE                      devstack      *LIBVIRT_TYPE: [libvirt type]*
-                                                              in devstack_localrc
-                                                              in the job vars.
-DEVSTACK_GATE_TEMPEST                           devstack      Defined by the job
-                                                tempest       that is used. The
-                                                              ``devstack`` job only
-                                                              runs devstack.
-                                                              The ``devstack-tempest``
-                                                              one triggers a Tempest
-                                                              run as well.
-DEVSTACK_GATE_TEMPEST_FULL                      tempest       *tox_envlist: full*
-                                                              in the job vars.
-DEVSTACK_GATE_TEMPEST_ALL                       tempest       *tox_envlist: all*
-                                                              in the job vars.
-DEVSTACK_GATE_TEMPEST_ALL_PLUGINS               tempest       *tox_envlist: all-plugin*
-                                                              in the job vars.
-DEVSTACK_GATE_TEMPEST_SCENARIOS                 tempest       *tox_envlist: scenario*
-                                                              in the job vars.
-TEMPEST_CONCURRENCY                             tempest       *tempest_concurrency: [value]*
-                                                              in the job vars. This
-                                                              is available only on
-                                                              jobs that inherit from
-                                                              ``devstack-tempest``
-                                                              down.
-DEVSTACK_GATE_TEMPEST_NOTESTS                   tempest       *tox_envlist: venv-tempest*
-                                                              in the job vars. This
-                                                              will create Tempest
-                                                              virtual environment
-                                                              but run no tests.
-DEVSTACK_GATE_SMOKE_SERIAL                      tempest       *tox_envlist: smoke-serial*
-                                                              in the job vars.
-DEVSTACK_GATE_TEMPEST_DISABLE_TENANT_ISOLATION  tempest       *tox_envlist: full-serial*
-                                                              in the job vars.
-                                                              *TEMPEST_ALLOW_TENANT_ISOLATION: false*
-                                                              in devstack_localrc in
-                                                              the job vars.
-==============================================  ============= ==================
+.. list-table:: **DevStack Gate Flags**
+   :widths: 20 10 60
+   :header-rows: 1
+
+   * - DevStack gate flag
+     - Repo
+     - New implementation
+   * - OVERRIDE_ZUUL_BRANCH
+     - zuul
+     - override-checkout: [branch] in the job definition.
+   * - DEVSTACK_GATE_NET_OVERLAY
+     - zuul-jobs
+     - A bridge called br-infra is set up for all jobs that inherit
+       from multinode with a dedicated `bridge role
+       <https://zuul-ci.org/docs/zuul-jobs/general-roles.html#role-multi-node-bridge>`_.
+   * - DEVSTACK_GATE_FEATURE_MATRIX
+     - devstack-gate
+     - ``test_matrix_features`` variable of the test-matrix role in
+       devstack-gate. This is a temporary solution, feature matrix
+       will go away. In the future services will be defined in jobs
+       only.
+   * - DEVSTACK_CINDER_VOLUME_CLEAR
+     - devstack
+     - *CINDER_VOLUME_CLEAR: true/false* in devstack_localrc in the
+       job vars.
+   * - DEVSTACK_GATE_NEUTRON
+     - devstack
+     - True by default. To disable, disable all neutron services in
+       devstack_services in the job definition.
+   * - DEVSTACK_GATE_CONFIGDRIVE
+     - devstack
+     - *FORCE_CONFIG_DRIVE: true/false* in devstack_localrc in the job
+       vars.
+   * - DEVSTACK_GATE_INSTALL_TESTONLY
+     - devstack
+     - *INSTALL_TESTONLY_PACKAGES: true/false* in devstack_localrc in
+       the job vars.
+   * - DEVSTACK_GATE_VIRT_DRIVER
+     - devstack
+     - *VIRT_DRIVER: [virt driver]* in devstack_localrc in the job
+       vars.
+   * - DEVSTACK_GATE_LIBVIRT_TYPE
+     - devstack
+     - *LIBVIRT_TYPE: [libvirt type]* in devstack_localrc in the job
+       vars.
+   * - DEVSTACK_GATE_TEMPEST
+     - devstack and tempest
+     - Defined by the job that is used. The ``devstack`` job only runs
+       devstack. The ``devstack-tempest`` one triggers a Tempest run
+       as well.
+   * - DEVSTACK_GATE_TEMPEST_FULL
+     - tempest
+     - *tox_envlist: full* in the job vars.
+   * - DEVSTACK_GATE_TEMPEST_ALL
+     - tempest
+     - *tox_envlist: all* in the job vars.
+   * - DEVSTACK_GATE_TEMPEST_ALL_PLUGINS
+     - tempest
+     - *tox_envlist: all-plugin* in the job vars.
+   * - DEVSTACK_GATE_TEMPEST_SCENARIOS
+     - tempest
+     - *tox_envlist: scenario* in the job vars.
+   * - TEMPEST_CONCURRENCY
+     - tempest
+     - *tempest_concurrency: [value]* in the job vars. This is
+       available only on jobs that inherit from ``devstack-tempest``
+       down.
+   * - DEVSTACK_GATE_TEMPEST_NOTESTS
+     - tempest
+     - *tox_envlist: venv-tempest* in the job vars. This will create
+       Tempest virtual environment but run no tests.
+   * - DEVSTACK_GATE_SMOKE_SERIAL
+     - tempest
+     - *tox_envlist: smoke-serial* in the job vars.
+   * - DEVSTACK_GATE_TEMPEST_DISABLE_TENANT_ISOLATION
+     - tempest
+     - *tox_envlist: full-serial* in the job vars.
+       *TEMPEST_ALLOW_TENANT_ISOLATION: false* in devstack_localrc in
+       the job vars.
+
 
 The following flags have not been migrated yet or are legacy and won't be
 migrated at all.
 
-=====================================  ======  ==========================
-DevStack gate flag                     Status  Details
-=====================================  ======  ==========================
-DEVSTACK_GATE_TOPOLOGY                 WIP     The topology depends on the base
-                                               job that is used and more
-                                               specifically on the nodeset
-                                               attached to it. The new job
-                                               format allows project to define
-                                               the variables to be passed to
-                                               every node/node-group that exists
-                                               in the topology. Named topologies
-                                               that include the nodeset and the
-                                               matching variables can be defined
-                                               in the form of base jobs.
-DEVSTACK_GATE_GRENADE                  TBD     Grenade Zuul V3 jobs will be
-                                               hosted in the grenade repo.
-GRENADE_BASE_BRANCH                    TBD     Grenade Zuul V3 jobs will be
-                                               hosted in the grenade repo.
-DEVSTACK_GATE_NEUTRON_DVR              TBD     Depends on multinode support.
-DEVSTACK_GATE_EXERCISES                TBD     Can be done on request.
-DEVSTACK_GATE_IRONIC                   TBD     This will probably be implemented
-                                               on ironic side.
-DEVSTACK_GATE_IRONIC_DRIVER            TBD     This will probably be implemented
-                                               on ironic side.
-DEVSTACK_GATE_IRONIC_BUILD_RAMDISK     TBD     This will probably be implemented
-                                               on ironic side.
-DEVSTACK_GATE_POSTGRES                 Legacy  This flag exists in d-g but the
-                                               only thing that it does is
-                                               capture postgres logs. This is
-                                               already supported by the roles in
-                                               post, so the flag is useless in
-                                               the new jobs. postgres itself can
-                                               be enabled via the
-                                               devstack_service job variable.
-DEVSTACK_GATE_ZEROMQ                   Legacy  This has no effect in d-g.
-DEVSTACK_GATE_MQ_DRIVER                Legacy  This has no effect in d-g.
-DEVSTACK_GATE_TEMPEST_STRESS_ARGS      Legacy  Stress is not in Tempest anymore.
-DEVSTACK_GATE_TEMPEST_HEAT_SLOW        Legacy  This is not used anywhere.
-DEVSTACK_GATE_CELLS                    Legacy  This has no effect in d-g.
-DEVSTACK_GATE_NOVA_API_METADATA_SPLIT  Legacy  This has no effect in d-g.
-=====================================  ======  ==========================
+.. list-table:: **Not Migrated DevStack Gate Flags**
+   :widths: 20 10 60
+   :header-rows: 1
+
+   * - DevStack gate flag
+     - Status
+     - Details
+   * - DEVSTACK_GATE_TOPOLOGY
+     - WIP
+     - The topology depends on the base job that is used and more
+       specifically on the nodeset attached to it. The new job format
+       allows project to define the variables to be passed to every
+       node/node-group that exists in the topology. Named topologies
+       that include the nodeset and the matching variables can be
+       defined in the form of base jobs.
+   * - DEVSTACK_GATE_GRENADE
+     - TBD
+     - Grenade Zuul V3 jobs will be hosted in the grenade repo.
+   * - GRENADE_BASE_BRANCH
+     - TBD
+     - Grenade Zuul V3 jobs will be hosted in the grenade repo.
+   * - DEVSTACK_GATE_NEUTRON_DVR
+     - TBD
+     - Depends on multinode support.
+   * - DEVSTACK_GATE_EXERCISES
+     - TBD
+     - Can be done on request.
+   * - DEVSTACK_GATE_IRONIC
+     - TBD
+     - This will probably be implemented on ironic side.
+   * - DEVSTACK_GATE_IRONIC_DRIVER
+     - TBD
+     - This will probably be implemented on ironic side.
+   * - DEVSTACK_GATE_IRONIC_BUILD_RAMDISK
+     - TBD
+     - This will probably be implemented on ironic side.
+   * - DEVSTACK_GATE_POSTGRES
+     - Legacy
+     - This flag exists in d-g but the only thing that it does is
+       capture postgres logs. This is already supported by the roles
+       in post, so the flag is useless in the new jobs. postgres
+       itself can be enabled via the devstack_service job variable.
+   * - DEVSTACK_GATE_ZEROMQ
+     - Legacy
+     - This has no effect in d-g.
+   * - DEVSTACK_GATE_MQ_DRIVER
+     - Legacy
+     - This has no effect in d-g.
+   * - DEVSTACK_GATE_TEMPEST_STRESS_ARGS
+     - Legacy
+     - Stress is not in Tempest anymore.
+   * - DEVSTACK_GATE_TEMPEST_HEAT_SLOW
+     - Legacy
+     - This is not used anywhere.
+   * - DEVSTACK_GATE_CELLS
+     - Legacy
+     - This has no effect in d-g.
+   * - DEVSTACK_GATE_NOVA_API_METADATA_SPLIT
+     - Legacy
+     - This has no effect in d-g.
diff --git a/lib/neutron b/lib/neutron
index 0d23d97..9c05c85 100644
--- a/lib/neutron
+++ b/lib/neutron
@@ -251,6 +251,7 @@
             if [[ "$NEUTRON_DISTRIBUTED_ROUTING" = "True" ]]; then
                 iniset $NEUTRON_CORE_PLUGIN_CONF agent l2_population True
                 iniset $NEUTRON_CORE_PLUGIN_CONF agent enable_distributed_routing True
+                iniset $NEUTRON_CORE_PLUGIN_CONF agent arp_responder True
             fi
         fi
 
diff --git a/lib/neutron_plugins/ml2 b/lib/neutron_plugins/ml2
index 127d46b..497b6c6 100644
--- a/lib/neutron_plugins/ml2
+++ b/lib/neutron_plugins/ml2
@@ -147,6 +147,7 @@
         populate_ml2_config /$Q_PLUGIN_CONF_FILE agent l2_population=True
         populate_ml2_config /$Q_PLUGIN_CONF_FILE agent tunnel_types=vxlan
         populate_ml2_config /$Q_PLUGIN_CONF_FILE agent enable_distributed_routing=True
+        populate_ml2_config /$Q_PLUGIN_CONF_FILE agent arp_responder=True
     fi
 }
 
diff --git a/lib/nova b/lib/nova
index fb106d7..449291e 100644
--- a/lib/nova
+++ b/lib/nova
@@ -399,7 +399,6 @@
     iniset $NOVA_CONF neutron default_floating_pool "$PUBLIC_NETWORK_NAME"
     if [[ $SERVICE_IP_VERSION == 6 ]]; then
         iniset $NOVA_CONF DEFAULT my_ip "$HOST_IPV6"
-        iniset $NOVA_CONF DEFAULT use_ipv6 "True"
     else
         iniset $NOVA_CONF DEFAULT my_ip "$HOST_IP"
     fi
diff --git a/lib/tls b/lib/tls
index 0032449..65ffeb9 100644
--- a/lib/tls
+++ b/lib/tls
@@ -234,6 +234,9 @@
                 # see https://bugs.python.org/issue23239
                 TLS_IP="DNS:$TLS_IP,IP:$TLS_IP"
             fi
+            if [[ -n "$HOST_IPV6" ]]; then
+                TLS_IP="$TLS_IP,IP:$HOST_IPV6"
+            fi
         fi
         make_cert $INT_CA_DIR $DEVSTACK_CERT_NAME $DEVSTACK_HOSTNAME "$TLS_IP"
 
diff --git a/roles/setup-devstack-source-dirs/README.rst b/roles/setup-devstack-source-dirs/README.rst
index 49d22c3..0aa048b 100644
--- a/roles/setup-devstack-source-dirs/README.rst
+++ b/roles/setup-devstack-source-dirs/README.rst
@@ -10,7 +10,7 @@
 
    The devstack base directory.
 
- .. zuul:rolevar:: devstack_sources_branch
-    :default: None
+.. zuul:rolevar:: devstack_sources_branch
+   :default: None
 
-    The target branch to be setup (where available).
+   The target branch to be setup (where available).
diff --git a/setup.cfg b/setup.cfg
index 825d386..4e27ad8 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -11,14 +11,5 @@
     License :: OSI Approved :: Apache Software License
     Operating System :: POSIX :: Linux
 
-[build_sphinx]
-all_files = 1
-build-dir = doc/build
-source-dir = doc/source
-warning-is-error = 1
-
-[pbr]
-warnerrors = True
-
 [wheel]
 universal = 1
diff --git a/stack.sh b/stack.sh
index 3c31644..2544900 100755
--- a/stack.sh
+++ b/stack.sh
@@ -247,7 +247,7 @@
 # --------------
 
 # We're not as **root** so make sure ``sudo`` is available
-is_package_installed sudo || install_package sudo
+is_package_installed sudo || is_package_installed sudo-ldap || install_package sudo
 
 # UEC images ``/etc/sudoers`` does not have a ``#includedir``, add one
 sudo grep -q "^#includedir.*/etc/sudoers.d" /etc/sudoers ||
diff --git a/tools/create-stack-user.sh b/tools/create-stack-user.sh
index c0b7ac7..919cacb 100755
--- a/tools/create-stack-user.sh
+++ b/tools/create-stack-user.sh
@@ -32,7 +32,7 @@
 source $TOP_DIR/stackrc
 
 # Give the non-root user the ability to run as **root** via ``sudo``
-is_package_installed sudo || install_package sudo
+is_package_installed sudo || is_package_installed sudo-ldap || install_package sudo
 
 [[ -z "$STACK_USER" ]] && die "STACK_USER is not set. Exiting."
 
diff --git a/tools/xen/README.md b/tools/xen/README.md
index 22263bb..2873011 100644
--- a/tools/xen/README.md
+++ b/tools/xen/README.md
@@ -1,3 +1,3 @@
 Note: XenServer relative tools have been moved to `os-xenapi`_ and be maintained there.
 
-.. _os-xenapi: https://github.com/openstack/os-xenapi/
+.. _os-xenapi: https://opendev.org/x/os-xenapi/
diff --git a/tox.ini b/tox.ini
index f643fdb..d81107f 100644
--- a/tox.ini
+++ b/tox.ini
@@ -41,7 +41,8 @@
 setenv =
   TOP_DIR={toxinidir}
 commands =
-  python setup.py build_sphinx
+  sphinx-build -W -b html -d doc/build/doctrees doc/source doc/build/html
+
 
 [testenv:venv]
 basepython = python3