Merge "Add openstacksdk functional job to devstack pipelines"
diff --git a/.gitignore b/.gitignore
index 956e13e..8fe56ad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,7 +28,7 @@
files/ir-deploy*
files/ironic-inspector*
files/etcd*
-^local.conf
+/local.conf
local.sh
localrc
proto
diff --git a/.zuul.yaml b/.zuul.yaml
index 7c2a9d5..c20f55c 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -148,6 +148,41 @@
nodes:
- compute1
+- nodeset:
+ name: openstack-three-node-bionic
+ nodes:
+ - name: controller
+ label: ubuntu-bionic
+ - name: compute1
+ label: ubuntu-bionic
+ - name: compute2
+ label: ubuntu-bionic
+ 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
+
- job:
name: devstack-base
parent: multinode
@@ -197,6 +232,7 @@
'{{ devstack_log_dir }}/dstat-csv.log': logs
'{{ devstack_log_dir }}/devstacklog.txt': logs
'{{ devstack_log_dir }}/devstacklog.txt.summary': logs
+ '{{ devstack_log_dir }}/tcpdump.pcap': logs
'{{ devstack_full_log}}': logs
'{{ stage_dir }}/verify_tempest_conf.log': logs
'{{ stage_dir }}/apache': logs
@@ -218,6 +254,7 @@
'{{ stage_dir }}/core': logs
'{{ stage_dir }}/listen53.txt': logs
'{{ stage_dir }}/deprecations.log': logs
+ '{{ stage_dir }}/audit.log': logs
/var/log/ceph: logs
/var/log/openvswitch: logs
/var/log/glusterfs: logs
@@ -581,7 +618,7 @@
- project:
templates:
- integrated-gate
- - integrated-gate-py35
+ - integrated-gate-py3
- publish-openstack-docs-pti
check:
jobs:
@@ -597,7 +634,7 @@
- devstack-multinode-xenial
- devstack-unit-tests
- openstack-tox-bashate
- - ironic-tempest-dsvm-ipa-wholedisk-bios-agent_ipmitool-tinyipa:
+ - ironic-tempest-ipa-wholedisk-bios-agent_ipmitool-tinyipa:
voting: false
- swift-dsvm-functional:
voting: false
diff --git a/README.rst b/README.rst
index 6885546..ad7ede4 100644
--- a/README.rst
+++ b/README.rst
@@ -38,7 +38,7 @@
`stackrc` for the default set). Usually just before a release there will be
milestone-proposed branches that need to be tested::
- GLANCE_REPO=git://git.openstack.org/openstack/glance.git
+ GLANCE_REPO=https://git.openstack.org/openstack/glance.git
GLANCE_BRANCH=milestone-proposed
Start A Dev Cloud
diff --git a/clean.sh b/clean.sh
index a29ebd9..d6c6b40 100755
--- a/clean.sh
+++ b/clean.sh
@@ -123,7 +123,7 @@
sudo rm -rf $LOGDIR
fi
-# Clean out the sytemd user unit files if systemd was used.
+# Clean out the systemd user unit files if systemd was used.
if [[ "$USE_SYSTEMD" = "True" ]]; then
sudo find $SYSTEMD_DIR -type f -name '*devstack@*service' -delete
# Make systemd aware of the deletion.
diff --git a/doc/source/debugging.rst b/doc/source/debugging.rst
new file mode 100644
index 0000000..fd0d9cd
--- /dev/null
+++ b/doc/source/debugging.rst
@@ -0,0 +1,46 @@
+=====================
+System-wide debugging
+=====================
+
+A lot can go wrong during a devstack run, and there are a few inbuilt
+tools to help you.
+
+dstat
+-----
+
+Enable the ``dstat`` service to produce performance logs during the
+devstack run. These will be logged to the journal and also as a CSV
+file.
+
+memory_tracker
+--------------
+
+The ``memory_tracker`` service periodically monitors RAM usage and
+provides consumption output when available memory is seen to be
+falling (i.e. processes are consuming memory). It also provides
+output showing locked (unswappable) memory.
+
+tcpdump
+-------
+
+Enable the ``tcpdump`` service to run a background tcpdump. You must
+set the ``TCPDUMP_ARGS`` variable to something suitable (there is no
+default). For example, to trace iSCSI communication during a job in
+the OpenStack gate and copy the result into the log output, you might
+use:
+
+.. code-block:: yaml
+
+ job:
+ name: devstack-job
+ parent: devstack
+ vars:
+ devstack_services:
+ tcpdump: true
+ devstack_localrc:
+ TCPDUMP_ARGS: "-i any tcp port 3260"
+ zuul_copy_output:
+ '{{ devstack_log_dir }}/tcpdump.pcap': logs
+
+
+
diff --git a/doc/source/guides/devstack-with-lbaas-v2.rst b/doc/source/guides/devstack-with-lbaas-v2.rst
index df3c7ce..b1d88cb 100644
--- a/doc/source/guides/devstack-with-lbaas-v2.rst
+++ b/doc/source/guides/devstack-with-lbaas-v2.rst
@@ -1,39 +1,54 @@
-Configure Load-Balancer Version 2
-=================================
+Devstack with Octavia Load Balancing
+====================================
-Starting in the OpenStack Liberty release, the
-`neutron LBaaS v2 API <https://developer.openstack.org/api-ref/network/v2/index.html>`_
-is now stable while the LBaaS v1 API has been deprecated. The LBaaS v2 reference
-driver is based on Octavia.
+Starting with the OpenStack Pike release, Octavia is now a standalone service
+providing load balancing services for OpenStack.
+This guide will show you how to create a devstack with `Octavia API`_ enabled.
+
+.. _Octavia API: https://developer.openstack.org/api-ref/load-balancer/v2/index.html
Phase 1: Create DevStack + 2 nova instances
--------------------------------------------
First, set up a vm of your choice with at least 8 GB RAM and 16 GB disk space,
-make sure it is updated. Install git and any other developer tools you find useful.
+make sure it is updated. Install git and any other developer tools you find
+useful.
Install devstack
::
git clone https://git.openstack.org/openstack-dev/devstack
- cd devstack
+ cd devstack/tools
+ sudo ./create-stack-user.sh
+ cd ../..
+ sudo mv devstack /opt/stack
+ sudo chown -R stack.stack /opt/stack/devstack
+This will clone the current devstack code locally, then setup the "stack"
+account that devstack services will run under. Finally, it will move devstack
+into its default location in /opt/stack/devstack.
-Edit your ``local.conf`` to look like
+Edit your ``/opt/stack/devstack/local.conf`` to look like
::
[[local|localrc]]
- # Load the external LBaaS plugin.
- enable_plugin neutron-lbaas https://git.openstack.org/openstack/neutron-lbaas
enable_plugin octavia https://git.openstack.org/openstack/octavia
+ # If you are enabling horizon, include the octavia dashboard
+ # enable_plugin octavia-dashboard https://git.openstack.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
+
+ # If you have python3 available:
+ # USE_PYTHON3=True
# ===== BEGIN localrc =====
DATABASE_PASSWORD=password
ADMIN_PASSWORD=password
SERVICE_PASSWORD=password
+ SERVICE_TOKEN=password
RABBIT_PASSWORD=password
# Enable Logging
LOGFILE=$DEST/logs/stack.sh.log
@@ -41,27 +56,30 @@
LOG_COLOR=True
# Pre-requisite
ENABLED_SERVICES=rabbit,mysql,key
- # Horizon
- ENABLED_SERVICES+=,horizon
+ # Horizon - enable for the OpenStack web GUI
+ # ENABLED_SERVICES+=,horizon
# Nova
- ENABLED_SERVICES+=,n-api,n-cpu,n-cond,n-sch
+ ENABLED_SERVICES+=,n-api,n-crt,n-obj,n-cpu,n-cond,n-sch,n-api-meta,n-sproxy
+ ENABLED_SERVICES+=,placement-api,placement-client
# Glance
ENABLED_SERVICES+=,g-api,g-reg
# Neutron
- ENABLED_SERVICES+=,q-svc,q-agt,q-dhcp,q-l3,q-meta
- # Enable LBaaS v2
- ENABLED_SERVICES+=,q-lbaasv2
+ ENABLED_SERVICES+=,q-svc,q-agt,q-dhcp,q-l3,q-meta,neutron
ENABLED_SERVICES+=,octavia,o-cw,o-hk,o-hm,o-api
# Cinder
ENABLED_SERVICES+=,c-api,c-vol,c-sch
# Tempest
ENABLED_SERVICES+=,tempest
+ # Barbican - Optionally used for TLS offload in Octavia
+ # ENABLED_SERVICES+=,barbican
# ===== END localrc =====
Run stack.sh and do some sanity checks
::
+ sudo su - stack
+ cd /opt/stack/devstack
./stack.sh
. ./openrc
@@ -72,38 +90,59 @@
::
#create nova instances on private network
- nova boot --image $(nova image-list | awk '/ cirros-.*-x86_64-uec / {print $2}') --flavor 1 --nic net-id=$(openstack network list | awk '/ private / {print $2}') node1
- nova boot --image $(nova image-list | awk '/ cirros-.*-x86_64-uec / {print $2}') --flavor 1 --nic net-id=$(openstack network list | awk '/ private / {print $2}') node2
- nova list # should show the nova instances just created
+ openstack server create --image $(openstack image list | awk '/ cirros-.*-x86_64-.* / {print $2}') --flavor 1 --nic net-id=$(openstack network list | awk '/ private / {print $2}') node1
+ openstack server creeate --image $(openstack image list | awk '/ cirros-.*-x86_64-.* / {print $2}') --flavor 1 --nic net-id=$(openstack network list | awk '/ private / {print $2}') node2
+ openstack server list # should show the nova instances just created
#add secgroup rules to allow ssh etc..
openstack security group rule create default --protocol icmp
openstack security group rule create default --protocol tcp --dst-port 22:22
openstack security group rule create default --protocol tcp --dst-port 80:80
-Set up a simple web server on each of these instances. ssh into each instance (username 'cirros', password 'cubswin:)') and run
+Set up a simple web server on each of these instances. ssh into each instance (username 'cirros', password 'cubswin:)' or 'gocubsgo') and run
::
MYIP=$(ifconfig eth0|grep 'inet addr'|awk -F: '{print $2}'| awk '{print $1}')
while true; do echo -e "HTTP/1.0 200 OK\r\n\r\nWelcome to $MYIP" | sudo nc -l -p 80 ; done&
-Phase 2: Create your load balancers
-------------------------------------
+Phase 2: Create your load balancer
+----------------------------------
+
+Make sure you have the 'openstack loadbalancer' commands:
::
- neutron lbaas-loadbalancer-create --name lb1 private-subnet
- neutron lbaas-loadbalancer-show lb1 # Wait for the provisioning_status to be ACTIVE.
- neutron lbaas-listener-create --loadbalancer lb1 --protocol HTTP --protocol-port 80 --name listener1
- sleep 10 # Sleep since LBaaS actions can take a few seconds depending on the environment.
- neutron lbaas-pool-create --lb-algorithm ROUND_ROBIN --listener listener1 --protocol HTTP --name pool1
- sleep 10
- neutron lbaas-member-create --subnet private-subnet --address 10.0.0.3 --protocol-port 80 pool1
- sleep 10
- neutron lbaas-member-create --subnet private-subnet --address 10.0.0.5 --protocol-port 80 pool1
+ pip install python-octaviaclient
-Please note here that the "10.0.0.3" and "10.0.0.5" in the above commands are the IPs of the nodes
-(in my test run-thru, they were actually 10.2 and 10.4), and the address of the created LB will be
-reported as "vip_address" from the lbaas-loadbalancer-create, and a quick test of that LB is
-"curl that-lb-ip", which should alternate between showing the IPs of the two nodes.
+Create your load balancer:
+
+::
+
+ openstack loadbalancer create --name lb1 --vip-subnet-id private-subnet
+ openstack loadbalancer show lb1 # Wait for the provisioning_status to be ACTIVE.
+ openstack loadbalancer listener create --protocol HTTP --protocol-port 80 --name listener1 lb1
+ openstack loadbalancer show lb1 # Wait for the provisioning_status to be ACTIVE.
+ openstack loadbalancer pool create --lb-algorithm ROUND_ROBIN --listener listener1 --protocol HTTP --name pool1
+ openstack loadbalancer show lb1 # Wait for the provisioning_status to be ACTIVE.
+ openstack loadbalancer healthmonitor create --delay 5 --timeout 2 --max-retries 1 --type HTTP pool1
+ openstack loadbalancer show lb1 # Wait for the provisioning_status to be ACTIVE.
+ openstack loadbalancer member create --subnet-id private-subnet --address <web server 1 address> --protocol-port 80 pool1
+ openstack loadbalancer show lb1 # Wait for the provisioning_status to be ACTIVE.
+ openstack loadbalancer member create --subnet-id private-subnet --address <web server 2 address> --protocol-port 80 pool1
+
+Please note: The <web server # address> fields are the IP addresses of the nova
+servers created in Phase 1.
+Also note, using the API directly you can do all of the above commands in one
+API call.
+
+Phase 3: Test your load balancer
+--------------------------------
+
+::
+
+ openstack loadbalancer show lb1 # Note the vip_address
+ curl http://<vip_address>
+ curl http://<vip_address>
+
+This should show the "Welcome to <IP>" message from each member server.
diff --git a/doc/source/guides/devstack-with-ldap.rst b/doc/source/guides/devstack-with-ldap.rst
index ec41141..4c54723 100644
--- a/doc/source/guides/devstack-with-ldap.rst
+++ b/doc/source/guides/devstack-with-ldap.rst
@@ -12,14 +12,14 @@
LDAP support in keystone is read-only. You can use it to back an entire
OpenStack deployment to a single LDAP server, or you can use it to back
separate LDAP servers to specific keystone domains. Users within those domains
-will can authenticate against keystone, assume role assignments, and interact
-with other OpenStack services.
+can authenticate against keystone, assume role assignments, and interact with
+other OpenStack services.
Configuration
=============
To deploy an OpenLDAP server, make sure ``ldap`` is added to the list of
-``ENABLED_SERVICES``::
+``ENABLED_SERVICES`` in the ``local.conf`` file::
enable_service ldap
@@ -35,9 +35,9 @@
At this point, devstack should have everything it needs to deploy OpenLDAP,
bootstrap it with a minimal set of users, and configure it to back to a domain
-in keystone::
+in keystone. You can do this by running the ``stack.sh`` script::
- ./stack.sh
+ $ ./stack.sh
Once ``stack.sh`` completes, you should have a running keystone deployment with
a basic set of users. It is important to note that not all users will live
@@ -63,7 +63,7 @@
To list all users in LDAP directly, you can use ``ldapsearch`` with the LDAP
user bootstrapped by devstack::
- ldapsearch -x -w LDAP_PASSWORD -D cn=Manager,dc=openstack,dc=org \
+ $ ldapsearch -x -w LDAP_PASSWORD -D cn=Manager,dc=openstack,dc=org \
-H ldap://localhost -b dc=openstack,dc=org
As you can see, devstack creates an OpenStack domain called ``openstack.org``
@@ -93,7 +93,7 @@
Now, we use the ``Manager`` user to create a user for Peter in LDAP::
- ldapadd -x -w LDAP_PASSWORD -D cn=Manager,dc=openstack,dc=org \
+ $ ldapadd -x -w LDAP_PASSWORD -D cn=Manager,dc=openstack,dc=org \
-H ldap://localhost -c -f peter.ldif.in
We should be able to assign Peter roles on projects. After Peter has some level
@@ -125,7 +125,7 @@
We can use the same basic steps to remove users from LDAP, but instead of using
LDIFs, we can just pass the ``dn`` of the user we want to delete::
- ldapdelete -x -w LDAP_PASSWORD -D cn=Manager,dc=openstack,dc=org \
+ $ ldapdelete -x -w LDAP_PASSWORD -D cn=Manager,dc=openstack,dc=org \
-H ldap://localhost cn=peter,ou=Users,dc=openstack,dc=org
Group Management
@@ -153,7 +153,7 @@
We can create the group using the same ``ldapadd`` command as we did with
users::
- ldapadd -x -w LDAP_PASSWORD -D cn=Manager,dc=openstack,dc=org \
+ $ ldapadd -x -w LDAP_PASSWORD -D cn=Manager,dc=openstack,dc=org \
-H ldap://localhost -c -f guardian-group.ldif.in
If we check the group membership in Horizon, we'll see that only Peter is a
@@ -167,7 +167,7 @@
Just like users, groups can be deleted using the ``dn``::
- ldapdelete -x -w LDAP_PASSWORD -D cn=Manager,dc=openstack,dc=org \
+ $ ldapdelete -x -w LDAP_PASSWORD -D cn=Manager,dc=openstack,dc=org \
-H ldap://localhost cn=guardians,ou=UserGroups,dc=openstack,dc=org
Note that this operation will not remove users within that group. It will only
diff --git a/doc/source/guides/multinode-lab.rst b/doc/source/guides/multinode-lab.rst
index b4e2891..c3574ac 100644
--- a/doc/source/guides/multinode-lab.rst
+++ b/doc/source/guides/multinode-lab.rst
@@ -177,7 +177,7 @@
GLANCE_HOSTPORT=$SERVICE_HOST:9292
ENABLED_SERVICES=n-cpu,q-agt,n-api-meta,c-vol,placement-client
NOVA_VNC_ENABLED=True
- NOVNCPROXY_URL="http://$SERVICE_HOST:6080/vnc_auto.html"
+ NOVNCPROXY_URL="http://$SERVICE_HOST:6080/vnc_lite.html"
VNCSERVER_LISTEN=$HOST_IP
VNCSERVER_PROXYCLIENT_ADDRESS=$VNCSERVER_LISTEN
@@ -240,8 +240,8 @@
sudo rm -rf /etc/libvirt/qemu/inst*
sudo virsh list | grep inst | awk '{print $1}' | xargs -n1 virsh destroy
-Options pimp your stack
-=======================
+Going further
+=============
Additional Users
----------------
@@ -302,10 +302,10 @@
DevStack will automatically use an existing LVM volume group named
``stack-volumes`` to store cloud-created volumes. If ``stack-volumes``
-doesn't exist, DevStack will set up a 10Gb loop-mounted file to contain
-it. This obviously limits the number and size of volumes that can be
-created inside OpenStack. The size can be overridden by setting
-``VOLUME_BACKING_FILE_SIZE`` in ``local.conf``.
+doesn't exist, DevStack will set up a loop-mounted file to contain
+it. If the default size is insufficient for the number and size of volumes
+required, it can be overridden by setting ``VOLUME_BACKING_FILE_SIZE`` in
+``local.conf`` (sizes given in ``truncate`` compatible format, e.g. ``24G``).
``stack-volumes`` can be pre-created on any physical volume supported by
Linux's LVM. The name of the volume group can be changed by setting
@@ -369,17 +369,6 @@
Notes stuff you might need to know
==================================
-Reset the Bridge
-----------------
-
-How to reset the bridge configuration:
-
-::
-
- sudo brctl delif br100 eth0.926
- sudo ip link set dev br100 down
- sudo brctl delbr br100
-
Set MySQL Password
------------------
diff --git a/doc/source/guides/neutron.rst b/doc/source/guides/neutron.rst
index 12c6d69..80b2f85 100644
--- a/doc/source/guides/neutron.rst
+++ b/doc/source/guides/neutron.rst
@@ -567,7 +567,7 @@
Q_ML2_PLUGIN_MECHANISM_DRIVERS=macvtap
Q_USE_PROVIDER_NETWORKING=True
- enable_plugin neutron git://git.openstack.org/openstack/neutron
+ enable_plugin neutron https://git.openstack.org/openstack/neutron
## MacVTap agent options
Q_AGENT=macvtap
@@ -622,7 +622,7 @@
# Services that a compute node runs
disable_all_services
- enable_plugin neutron git://git.openstack.org/openstack/neutron
+ enable_plugin neutron https://git.openstack.org/openstack/neutron
ENABLED_SERVICES+=n-cpu,q-agt
## MacVTap agent options
diff --git a/doc/source/guides/nova.rst b/doc/source/guides/nova.rst
index 0f105d7..65491d1 100644
--- a/doc/source/guides/nova.rst
+++ b/doc/source/guides/nova.rst
@@ -68,3 +68,69 @@
For more information on OpenStack configuration see the `OpenStack
Compute Service Configuration Reference
<https://docs.openstack.org/nova/latest/admin/configuration/index.html>`_
+
+
+Fake virt driver
+================
+
+Nova has a `fake virt driver`_ which can be used for scale testing the control
+plane services or testing "move" operations between fake compute nodes, for
+example cold/live migration, evacuate and unshelve.
+
+The fake virt driver does not communicate with any hypervisor, it just reports
+some fake resource inventory values and keeps track of the state of the
+"guests" created, moved and deleted. It is not feature-complete with the
+compute API but is good enough for most API testing, and is also used within
+the nova functional tests themselves so is fairly robust.
+
+.. _fake virt driver: http://git.openstack.org/cgit/openstack/nova/tree/nova/virt/fake.py
+
+Configuration
+-------------
+
+Set the following in your devstack ``local.conf``:
+
+.. code-block:: ini
+
+ [[local|localrc]]
+ VIRT_DRIVER=fake
+ NUMBER_FAKE_NOVA_COMPUTE=<number>
+
+The ``NUMBER_FAKE_NOVA_COMPUTE`` variable controls the number of fake
+``nova-compute`` services to run and defaults to 1.
+
+When ``VIRT_DRIVER=fake`` is used, devstack will disable quota checking in
+nova and neutron automatically. However, other services, like cinder, will
+still enforce quota limits by default.
+
+Scaling
+-------
+
+The actual value to use for ``NUMBER_FAKE_NOVA_COMPUTE`` depends on factors
+such as:
+
+* The size of the host (physical or virtualized) on which devstack is running.
+* The number of API workers. By default, devstack will run ``max($nproc/2, 2)``
+ workers per API service. If you are running several fake compute services on
+ a single host, then consider setting ``API_WORKERS=1`` in ``local.conf``.
+
+In addition, while quota will be disabled in neutron, there is no fake ML2
+backend for neutron so creating fake VMs will still result in real ports being
+created. To create servers without networking, you can specify ``--nic=none``
+when creating the server, for example:
+
+.. code-block:: shell
+
+ $ openstack --os-compute-api-version 2.37 server create --flavor cirros256 \
+ --image cirros-0.3.5-x86_64-disk --nic none --wait test-server
+
+.. note:: ``--os-compute-api-version`` greater than or equal to 2.37 is
+ required to use ``--nic=none``.
+
+To avoid overhead from other services which you may not need, disable them in
+your ``local.conf``, for example:
+
+.. code-block:: ini
+
+ disable_service horizon
+ disable_service tempest
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 6c42a5b..1ea1c5d 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -38,22 +38,23 @@
Install Linux
-------------
-Start with a clean and minimal install of a Linux system. Devstack
+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.
-If you do not have a preference, Ubuntu 16.04 is the most tested, and
-will probably go the smoothest.
+If you do not have a preference, Ubuntu 18.04 (Bionic Beaver) is the
+most tested, and will probably go the smoothest.
-Add Stack User
---------------
+Add Stack User (optional)
+-------------------------
-Devstack should be run as a non-root user with sudo enabled
+DevStack should be run as a non-root user with sudo enabled
(standard logins to cloud images such as "ubuntu" or "cloud-user"
are usually fine).
-You can quickly create a separate `stack` user to run DevStack with
+If you are not using a cloud image, you can create a separate `stack` user
+to run DevStack with
.. code-block:: console
@@ -76,12 +77,12 @@
$ cd devstack
The ``devstack`` repo contains a script that installs OpenStack and
-templates for configuration files
+templates for configuration files.
Create a local.conf
-------------------
-Create a ``local.conf`` file with 4 passwords preset at the root of the
+Create a ``local.conf`` file with four passwords preset at the root of the
devstack git repo.
.. code-block:: ini
@@ -114,8 +115,8 @@
You now have a working DevStack! Congrats!
Your devstack will have installed ``keystone``, ``glance``, ``nova``,
-``cinder``, ``neutron``, and ``horizon``. Floating IPs will be
-available, guests have access to the external world.
+``placement``, ``cinder``, ``neutron``, and ``horizon``. Floating IPs
+will be available, guests have access to the external world.
You can access horizon to experience the web interface to
OpenStack, and manage vms, networks, volumes, and images from
diff --git a/doc/source/overview.rst b/doc/source/overview.rst
index 2479cd0..a609333 100644
--- a/doc/source/overview.rst
+++ b/doc/source/overview.rst
@@ -64,7 +64,8 @@
The default services configured by DevStack are Identity (keystone),
Object Storage (swift), Image Service (glance), Block Storage
-(cinder), Compute (nova), Networking (neutron), Dashboard (horizon)
+(cinder), Compute (nova), Placement (placement),
+Networking (neutron), Dashboard (horizon).
Additional services not included directly in DevStack can be tied in to
``stack.sh`` using the :doc:`plugin mechanism <plugins>` to call
diff --git a/doc/source/plugin-registry.rst b/doc/source/plugin-registry.rst
index 02d6911..9338d18 100644
--- a/doc/source/plugin-registry.rst
+++ b/doc/source/plugin-registry.rst
@@ -24,179 +24,182 @@
====================================== ===
Plugin Name URL
====================================== ===
-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>`__
-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>`__
-broadview-collector `git://git.openstack.org/openstack/broadview-collector <https://git.openstack.org/cgit/openstack/broadview-collector>`__
-castellan-ui `git://git.openstack.org/openstack/castellan-ui <https://git.openstack.org/cgit/openstack/castellan-ui>`__
-ceilometer `git://git.openstack.org/openstack/ceilometer <https://git.openstack.org/cgit/openstack/ceilometer>`__
-ceilometer-powervm `git://git.openstack.org/openstack/ceilometer-powervm <https://git.openstack.org/cgit/openstack/ceilometer-powervm>`__
-cloudkitty `git://git.openstack.org/openstack/cloudkitty <https://git.openstack.org/cgit/openstack/cloudkitty>`__
-collectd-openstack-plugins `git://git.openstack.org/openstack/collectd-openstack-plugins <https://git.openstack.org/cgit/openstack/collectd-openstack-plugins>`__
-congress `git://git.openstack.org/openstack/congress <https://git.openstack.org/cgit/openstack/congress>`__
-cyborg `git://git.openstack.org/openstack/cyborg <https://git.openstack.org/cgit/openstack/cyborg>`__
-designate `git://git.openstack.org/openstack/designate <https://git.openstack.org/cgit/openstack/designate>`__
-devstack-plugin-additional-pkg-repos `git://git.openstack.org/openstack/devstack-plugin-additional-pkg-repos <https://git.openstack.org/cgit/openstack/devstack-plugin-additional-pkg-repos>`__
-devstack-plugin-amqp1 `git://git.openstack.org/openstack/devstack-plugin-amqp1 <https://git.openstack.org/cgit/openstack/devstack-plugin-amqp1>`__
-devstack-plugin-bdd `git://git.openstack.org/openstack/devstack-plugin-bdd <https://git.openstack.org/cgit/openstack/devstack-plugin-bdd>`__
-devstack-plugin-ceph `git://git.openstack.org/openstack/devstack-plugin-ceph <https://git.openstack.org/cgit/openstack/devstack-plugin-ceph>`__
-devstack-plugin-container `git://git.openstack.org/openstack/devstack-plugin-container <https://git.openstack.org/cgit/openstack/devstack-plugin-container>`__
-devstack-plugin-glusterfs `git://git.openstack.org/openstack/devstack-plugin-glusterfs <https://git.openstack.org/cgit/openstack/devstack-plugin-glusterfs>`__
-devstack-plugin-hdfs `git://git.openstack.org/openstack/devstack-plugin-hdfs <https://git.openstack.org/cgit/openstack/devstack-plugin-hdfs>`__
-devstack-plugin-kafka `git://git.openstack.org/openstack/devstack-plugin-kafka <https://git.openstack.org/cgit/openstack/devstack-plugin-kafka>`__
-devstack-plugin-libvirt-qemu `git://git.openstack.org/openstack/devstack-plugin-libvirt-qemu <https://git.openstack.org/cgit/openstack/devstack-plugin-libvirt-qemu>`__
-devstack-plugin-mariadb `git://git.openstack.org/openstack/devstack-plugin-mariadb <https://git.openstack.org/cgit/openstack/devstack-plugin-mariadb>`__
-devstack-plugin-nfs `git://git.openstack.org/openstack/devstack-plugin-nfs <https://git.openstack.org/cgit/openstack/devstack-plugin-nfs>`__
-devstack-plugin-pika `git://git.openstack.org/openstack/devstack-plugin-pika <https://git.openstack.org/cgit/openstack/devstack-plugin-pika>`__
-devstack-plugin-sheepdog `git://git.openstack.org/openstack/devstack-plugin-sheepdog <https://git.openstack.org/cgit/openstack/devstack-plugin-sheepdog>`__
-devstack-plugin-vmax `git://git.openstack.org/openstack/devstack-plugin-vmax <https://git.openstack.org/cgit/openstack/devstack-plugin-vmax>`__
-devstack-plugin-zmq `git://git.openstack.org/openstack/devstack-plugin-zmq <https://git.openstack.org/cgit/openstack/devstack-plugin-zmq>`__
-dragonflow `git://git.openstack.org/openstack/dragonflow <https://git.openstack.org/cgit/openstack/dragonflow>`__
-drbd-devstack `git://git.openstack.org/openstack/drbd-devstack <https://git.openstack.org/cgit/openstack/drbd-devstack>`__
-ec2-api `git://git.openstack.org/openstack/ec2-api <https://git.openstack.org/cgit/openstack/ec2-api>`__
-freezer `git://git.openstack.org/openstack/freezer <https://git.openstack.org/cgit/openstack/freezer>`__
-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>`__
-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>`__
-ironic `git://git.openstack.org/openstack/ironic <https://git.openstack.org/cgit/openstack/ironic>`__
-ironic-inspector `git://git.openstack.org/openstack/ironic-inspector <https://git.openstack.org/cgit/openstack/ironic-inspector>`__
-ironic-staging-drivers `git://git.openstack.org/openstack/ironic-staging-drivers <https://git.openstack.org/cgit/openstack/ironic-staging-drivers>`__
-ironic-ui `git://git.openstack.org/openstack/ironic-ui <https://git.openstack.org/cgit/openstack/ironic-ui>`__
-karbor `git://git.openstack.org/openstack/karbor <https://git.openstack.org/cgit/openstack/karbor>`__
-karbor-dashboard `git://git.openstack.org/openstack/karbor-dashboard <https://git.openstack.org/cgit/openstack/karbor-dashboard>`__
-keystone `git://git.openstack.org/openstack/keystone <https://git.openstack.org/cgit/openstack/keystone>`__
-kingbird `git://git.openstack.org/openstack/kingbird <https://git.openstack.org/cgit/openstack/kingbird>`__
-kuryr-kubernetes `git://git.openstack.org/openstack/kuryr-kubernetes <https://git.openstack.org/cgit/openstack/kuryr-kubernetes>`__
-kuryr-libnetwork `git://git.openstack.org/openstack/kuryr-libnetwork <https://git.openstack.org/cgit/openstack/kuryr-libnetwork>`__
-kuryr-tempest-plugin `git://git.openstack.org/openstack/kuryr-tempest-plugin <https://git.openstack.org/cgit/openstack/kuryr-tempest-plugin>`__
-magnum `git://git.openstack.org/openstack/magnum <https://git.openstack.org/cgit/openstack/magnum>`__
-magnum-ui `git://git.openstack.org/openstack/magnum-ui <https://git.openstack.org/cgit/openstack/magnum-ui>`__
-manila `git://git.openstack.org/openstack/manila <https://git.openstack.org/cgit/openstack/manila>`__
-manila-ui `git://git.openstack.org/openstack/manila-ui <https://git.openstack.org/cgit/openstack/manila-ui>`__
-masakari `git://git.openstack.org/openstack/masakari <https://git.openstack.org/cgit/openstack/masakari>`__
-meteos `git://git.openstack.org/openstack/meteos <https://git.openstack.org/cgit/openstack/meteos>`__
-meteos-ui `git://git.openstack.org/openstack/meteos-ui <https://git.openstack.org/cgit/openstack/meteos-ui>`__
-mistral `git://git.openstack.org/openstack/mistral <https://git.openstack.org/cgit/openstack/mistral>`__
-mixmatch `git://git.openstack.org/openstack/mixmatch <https://git.openstack.org/cgit/openstack/mixmatch>`__
-mogan `git://git.openstack.org/openstack/mogan <https://git.openstack.org/cgit/openstack/mogan>`__
-mogan-ui `git://git.openstack.org/openstack/mogan-ui <https://git.openstack.org/cgit/openstack/mogan-ui>`__
-monasca-analytics `git://git.openstack.org/openstack/monasca-analytics <https://git.openstack.org/cgit/openstack/monasca-analytics>`__
-monasca-api `git://git.openstack.org/openstack/monasca-api <https://git.openstack.org/cgit/openstack/monasca-api>`__
-monasca-ceilometer `git://git.openstack.org/openstack/monasca-ceilometer <https://git.openstack.org/cgit/openstack/monasca-ceilometer>`__
-monasca-events-api `git://git.openstack.org/openstack/monasca-events-api <https://git.openstack.org/cgit/openstack/monasca-events-api>`__
-monasca-log-api `git://git.openstack.org/openstack/monasca-log-api <https://git.openstack.org/cgit/openstack/monasca-log-api>`__
-monasca-tempest-plugin `git://git.openstack.org/openstack/monasca-tempest-plugin <https://git.openstack.org/cgit/openstack/monasca-tempest-plugin>`__
-monasca-transform `git://git.openstack.org/openstack/monasca-transform <https://git.openstack.org/cgit/openstack/monasca-transform>`__
-murano `git://git.openstack.org/openstack/murano <https://git.openstack.org/cgit/openstack/murano>`__
-networking-6wind `git://git.openstack.org/openstack/networking-6wind <https://git.openstack.org/cgit/openstack/networking-6wind>`__
-networking-ansible `git://git.openstack.org/openstack/networking-ansible <https://git.openstack.org/cgit/openstack/networking-ansible>`__
-networking-arista `git://git.openstack.org/openstack/networking-arista <https://git.openstack.org/cgit/openstack/networking-arista>`__
-networking-bagpipe `git://git.openstack.org/openstack/networking-bagpipe <https://git.openstack.org/cgit/openstack/networking-bagpipe>`__
-networking-baremetal `git://git.openstack.org/openstack/networking-baremetal <https://git.openstack.org/cgit/openstack/networking-baremetal>`__
-networking-bgpvpn `git://git.openstack.org/openstack/networking-bgpvpn <https://git.openstack.org/cgit/openstack/networking-bgpvpn>`__
-networking-brocade `git://git.openstack.org/openstack/networking-brocade <https://git.openstack.org/cgit/openstack/networking-brocade>`__
-networking-calico `git://git.openstack.org/openstack/networking-calico <https://git.openstack.org/cgit/openstack/networking-calico>`__
-networking-cisco `git://git.openstack.org/openstack/networking-cisco <https://git.openstack.org/cgit/openstack/networking-cisco>`__
-networking-cumulus `git://git.openstack.org/openstack/networking-cumulus <https://git.openstack.org/cgit/openstack/networking-cumulus>`__
-networking-dpm `git://git.openstack.org/openstack/networking-dpm <https://git.openstack.org/cgit/openstack/networking-dpm>`__
-networking-fortinet `git://git.openstack.org/openstack/networking-fortinet <https://git.openstack.org/cgit/openstack/networking-fortinet>`__
-networking-generic-switch `git://git.openstack.org/openstack/networking-generic-switch <https://git.openstack.org/cgit/openstack/networking-generic-switch>`__
-networking-hpe `git://git.openstack.org/openstack/networking-hpe <https://git.openstack.org/cgit/openstack/networking-hpe>`__
-networking-huawei `git://git.openstack.org/openstack/networking-huawei <https://git.openstack.org/cgit/openstack/networking-huawei>`__
-networking-hyperv `git://git.openstack.org/openstack/networking-hyperv <https://git.openstack.org/cgit/openstack/networking-hyperv>`__
-networking-infoblox `git://git.openstack.org/openstack/networking-infoblox <https://git.openstack.org/cgit/openstack/networking-infoblox>`__
-networking-l2gw `git://git.openstack.org/openstack/networking-l2gw <https://git.openstack.org/cgit/openstack/networking-l2gw>`__
-networking-lagopus `git://git.openstack.org/openstack/networking-lagopus <https://git.openstack.org/cgit/openstack/networking-lagopus>`__
-networking-midonet `git://git.openstack.org/openstack/networking-midonet <https://git.openstack.org/cgit/openstack/networking-midonet>`__
-networking-mlnx `git://git.openstack.org/openstack/networking-mlnx <https://git.openstack.org/cgit/openstack/networking-mlnx>`__
-networking-nec `git://git.openstack.org/openstack/networking-nec <https://git.openstack.org/cgit/openstack/networking-nec>`__
-networking-odl `git://git.openstack.org/openstack/networking-odl <https://git.openstack.org/cgit/openstack/networking-odl>`__
-networking-onos `git://git.openstack.org/openstack/networking-onos <https://git.openstack.org/cgit/openstack/networking-onos>`__
-networking-opencontrail `git://git.openstack.org/openstack/networking-opencontrail <https://git.openstack.org/cgit/openstack/networking-opencontrail>`__
-networking-ovn `git://git.openstack.org/openstack/networking-ovn <https://git.openstack.org/cgit/openstack/networking-ovn>`__
-networking-ovs-dpdk `git://git.openstack.org/openstack/networking-ovs-dpdk <https://git.openstack.org/cgit/openstack/networking-ovs-dpdk>`__
-networking-plumgrid `git://git.openstack.org/openstack/networking-plumgrid <https://git.openstack.org/cgit/openstack/networking-plumgrid>`__
-networking-powervm `git://git.openstack.org/openstack/networking-powervm <https://git.openstack.org/cgit/openstack/networking-powervm>`__
-networking-sfc `git://git.openstack.org/openstack/networking-sfc <https://git.openstack.org/cgit/openstack/networking-sfc>`__
-networking-spp `git://git.openstack.org/openstack/networking-spp <https://git.openstack.org/cgit/openstack/networking-spp>`__
-networking-vpp `git://git.openstack.org/openstack/networking-vpp <https://git.openstack.org/cgit/openstack/networking-vpp>`__
-networking-vsphere `git://git.openstack.org/openstack/networking-vsphere <https://git.openstack.org/cgit/openstack/networking-vsphere>`__
-neutron `git://git.openstack.org/openstack/neutron <https://git.openstack.org/cgit/openstack/neutron>`__
-neutron-classifier `git://git.openstack.org/openstack/neutron-classifier <https://git.openstack.org/cgit/openstack/neutron-classifier>`__
-neutron-dynamic-routing `git://git.openstack.org/openstack/neutron-dynamic-routing <https://git.openstack.org/cgit/openstack/neutron-dynamic-routing>`__
-neutron-fwaas `git://git.openstack.org/openstack/neutron-fwaas <https://git.openstack.org/cgit/openstack/neutron-fwaas>`__
-neutron-fwaas-dashboard `git://git.openstack.org/openstack/neutron-fwaas-dashboard <https://git.openstack.org/cgit/openstack/neutron-fwaas-dashboard>`__
-neutron-lbaas `git://git.openstack.org/openstack/neutron-lbaas <https://git.openstack.org/cgit/openstack/neutron-lbaas>`__
-neutron-lbaas-dashboard `git://git.openstack.org/openstack/neutron-lbaas-dashboard <https://git.openstack.org/cgit/openstack/neutron-lbaas-dashboard>`__
-neutron-tempest-plugin `git://git.openstack.org/openstack/neutron-tempest-plugin <https://git.openstack.org/cgit/openstack/neutron-tempest-plugin>`__
-neutron-vpnaas `git://git.openstack.org/openstack/neutron-vpnaas <https://git.openstack.org/cgit/openstack/neutron-vpnaas>`__
-neutron-vpnaas-dashboard `git://git.openstack.org/openstack/neutron-vpnaas-dashboard <https://git.openstack.org/cgit/openstack/neutron-vpnaas-dashboard>`__
-nova-dpm `git://git.openstack.org/openstack/nova-dpm <https://git.openstack.org/cgit/openstack/nova-dpm>`__
-nova-lxd `git://git.openstack.org/openstack/nova-lxd <https://git.openstack.org/cgit/openstack/nova-lxd>`__
-nova-mksproxy `git://git.openstack.org/openstack/nova-mksproxy <https://git.openstack.org/cgit/openstack/nova-mksproxy>`__
-nova-powervm `git://git.openstack.org/openstack/nova-powervm <https://git.openstack.org/cgit/openstack/nova-powervm>`__
-oaktree `git://git.openstack.org/openstack/oaktree <https://git.openstack.org/cgit/openstack/oaktree>`__
-octavia `git://git.openstack.org/openstack/octavia <https://git.openstack.org/cgit/openstack/octavia>`__
-octavia-dashboard `git://git.openstack.org/openstack/octavia-dashboard <https://git.openstack.org/cgit/openstack/octavia-dashboard>`__
-omni `git://git.openstack.org/openstack/omni <https://git.openstack.org/cgit/openstack/omni>`__
-openstacksdk `git://git.openstack.org/openstack/openstacksdk <https://git.openstack.org/cgit/openstack/openstacksdk>`__
-os-xenapi `git://git.openstack.org/openstack/os-xenapi <https://git.openstack.org/cgit/openstack/os-xenapi>`__
-osprofiler `git://git.openstack.org/openstack/osprofiler <https://git.openstack.org/cgit/openstack/osprofiler>`__
-oswin-tempest-plugin `git://git.openstack.org/openstack/oswin-tempest-plugin <https://git.openstack.org/cgit/openstack/oswin-tempest-plugin>`__
-panko `git://git.openstack.org/openstack/panko <https://git.openstack.org/cgit/openstack/panko>`__
-patrole `git://git.openstack.org/openstack/patrole <https://git.openstack.org/cgit/openstack/patrole>`__
-picasso `git://git.openstack.org/openstack/picasso <https://git.openstack.org/cgit/openstack/picasso>`__
-qinling `git://git.openstack.org/openstack/qinling <https://git.openstack.org/cgit/openstack/qinling>`__
-qinling-dashboard `git://git.openstack.org/openstack/qinling-dashboard <https://git.openstack.org/cgit/openstack/qinling-dashboard>`__
-rally `git://git.openstack.org/openstack/rally <https://git.openstack.org/cgit/openstack/rally>`__
-rally-openstack `git://git.openstack.org/openstack/rally-openstack <https://git.openstack.org/cgit/openstack/rally-openstack>`__
-sahara `git://git.openstack.org/openstack/sahara <https://git.openstack.org/cgit/openstack/sahara>`__
-sahara-dashboard `git://git.openstack.org/openstack/sahara-dashboard <https://git.openstack.org/cgit/openstack/sahara-dashboard>`__
-scalpels `git://git.openstack.org/openstack/scalpels <https://git.openstack.org/cgit/openstack/scalpels>`__
-searchlight `git://git.openstack.org/openstack/searchlight <https://git.openstack.org/cgit/openstack/searchlight>`__
-searchlight-ui `git://git.openstack.org/openstack/searchlight-ui <https://git.openstack.org/cgit/openstack/searchlight-ui>`__
-senlin `git://git.openstack.org/openstack/senlin <https://git.openstack.org/cgit/openstack/senlin>`__
-slogging `git://git.openstack.org/openstack/slogging <https://git.openstack.org/cgit/openstack/slogging>`__
-solum `git://git.openstack.org/openstack/solum <https://git.openstack.org/cgit/openstack/solum>`__
-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-integ `git://git.openstack.org/openstack/stx-integ <https://git.openstack.org/cgit/openstack/stx-integ>`__
-stx-nfv `git://git.openstack.org/openstack/stx-nfv <https://git.openstack.org/cgit/openstack/stx-nfv>`__
-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>`__
-tatu `git://git.openstack.org/openstack/tatu <https://git.openstack.org/cgit/openstack/tatu>`__
-telemetry-tempest-plugin `git://git.openstack.org/openstack/telemetry-tempest-plugin <https://git.openstack.org/cgit/openstack/telemetry-tempest-plugin>`__
-tobiko `git://git.openstack.org/openstack/tobiko <https://git.openstack.org/cgit/openstack/tobiko>`__
-tricircle `git://git.openstack.org/openstack/tricircle <https://git.openstack.org/cgit/openstack/tricircle>`__
-trio2o `git://git.openstack.org/openstack/trio2o <https://git.openstack.org/cgit/openstack/trio2o>`__
-trove `git://git.openstack.org/openstack/trove <https://git.openstack.org/cgit/openstack/trove>`__
-trove-dashboard `git://git.openstack.org/openstack/trove-dashboard <https://git.openstack.org/cgit/openstack/trove-dashboard>`__
-valet `git://git.openstack.org/openstack/valet <https://git.openstack.org/cgit/openstack/valet>`__
-vitrage `git://git.openstack.org/openstack/vitrage <https://git.openstack.org/cgit/openstack/vitrage>`__
-vitrage-dashboard `git://git.openstack.org/openstack/vitrage-dashboard <https://git.openstack.org/cgit/openstack/vitrage-dashboard>`__
-vitrage-tempest-plugin `git://git.openstack.org/openstack/vitrage-tempest-plugin <https://git.openstack.org/cgit/openstack/vitrage-tempest-plugin>`__
-vmware-nsx `git://git.openstack.org/openstack/vmware-nsx <https://git.openstack.org/cgit/openstack/vmware-nsx>`__
-vmware-vspc `git://git.openstack.org/openstack/vmware-vspc <https://git.openstack.org/cgit/openstack/vmware-vspc>`__
-watcher `git://git.openstack.org/openstack/watcher <https://git.openstack.org/cgit/openstack/watcher>`__
-watcher-dashboard `git://git.openstack.org/openstack/watcher-dashboard <https://git.openstack.org/cgit/openstack/watcher-dashboard>`__
-zaqar `git://git.openstack.org/openstack/zaqar <https://git.openstack.org/cgit/openstack/zaqar>`__
-zaqar-ui `git://git.openstack.org/openstack/zaqar-ui <https://git.openstack.org/cgit/openstack/zaqar-ui>`__
-zun `git://git.openstack.org/openstack/zun <https://git.openstack.org/cgit/openstack/zun>`__
-zun-ui `git://git.openstack.org/openstack/zun-ui <https://git.openstack.org/cgit/openstack/zun-ui>`__
+almanach `https://git.openstack.org/openstack/almanach <https://git.openstack.org/cgit/openstack/almanach>`__
+aodh `https://git.openstack.org/openstack/aodh <https://git.openstack.org/cgit/openstack/aodh>`__
+apmec `https://git.openstack.org/openstack/apmec <https://git.openstack.org/cgit/openstack/apmec>`__
+barbican `https://git.openstack.org/openstack/barbican <https://git.openstack.org/cgit/openstack/barbican>`__
+bilean `https://git.openstack.org/openstack/bilean <https://git.openstack.org/cgit/openstack/bilean>`__
+blazar `https://git.openstack.org/openstack/blazar <https://git.openstack.org/cgit/openstack/blazar>`__
+broadview-collector `https://git.openstack.org/openstack/broadview-collector <https://git.openstack.org/cgit/openstack/broadview-collector>`__
+castellan-ui `https://git.openstack.org/openstack/castellan-ui <https://git.openstack.org/cgit/openstack/castellan-ui>`__
+ceilometer `https://git.openstack.org/openstack/ceilometer <https://git.openstack.org/cgit/openstack/ceilometer>`__
+ceilometer-powervm `https://git.openstack.org/openstack/ceilometer-powervm <https://git.openstack.org/cgit/openstack/ceilometer-powervm>`__
+cloudkitty `https://git.openstack.org/openstack/cloudkitty <https://git.openstack.org/cgit/openstack/cloudkitty>`__
+collectd-openstack-plugins `https://git.openstack.org/openstack/collectd-openstack-plugins <https://git.openstack.org/cgit/openstack/collectd-openstack-plugins>`__
+congress `https://git.openstack.org/openstack/congress <https://git.openstack.org/cgit/openstack/congress>`__
+cyborg `https://git.openstack.org/openstack/cyborg <https://git.openstack.org/cgit/openstack/cyborg>`__
+designate `https://git.openstack.org/openstack/designate <https://git.openstack.org/cgit/openstack/designate>`__
+devstack-plugin-additional-pkg-repos `https://git.openstack.org/openstack/devstack-plugin-additional-pkg-repos <https://git.openstack.org/cgit/openstack/devstack-plugin-additional-pkg-repos>`__
+devstack-plugin-amqp1 `https://git.openstack.org/openstack/devstack-plugin-amqp1 <https://git.openstack.org/cgit/openstack/devstack-plugin-amqp1>`__
+devstack-plugin-bdd `https://git.openstack.org/openstack/devstack-plugin-bdd <https://git.openstack.org/cgit/openstack/devstack-plugin-bdd>`__
+devstack-plugin-ceph `https://git.openstack.org/openstack/devstack-plugin-ceph <https://git.openstack.org/cgit/openstack/devstack-plugin-ceph>`__
+devstack-plugin-container `https://git.openstack.org/openstack/devstack-plugin-container <https://git.openstack.org/cgit/openstack/devstack-plugin-container>`__
+devstack-plugin-glusterfs `https://git.openstack.org/openstack/devstack-plugin-glusterfs <https://git.openstack.org/cgit/openstack/devstack-plugin-glusterfs>`__
+devstack-plugin-hdfs `https://git.openstack.org/openstack/devstack-plugin-hdfs <https://git.openstack.org/cgit/openstack/devstack-plugin-hdfs>`__
+devstack-plugin-kafka `https://git.openstack.org/openstack/devstack-plugin-kafka <https://git.openstack.org/cgit/openstack/devstack-plugin-kafka>`__
+devstack-plugin-libvirt-qemu `https://git.openstack.org/openstack/devstack-plugin-libvirt-qemu <https://git.openstack.org/cgit/openstack/devstack-plugin-libvirt-qemu>`__
+devstack-plugin-mariadb `https://git.openstack.org/openstack/devstack-plugin-mariadb <https://git.openstack.org/cgit/openstack/devstack-plugin-mariadb>`__
+devstack-plugin-nfs `https://git.openstack.org/openstack/devstack-plugin-nfs <https://git.openstack.org/cgit/openstack/devstack-plugin-nfs>`__
+devstack-plugin-pika `https://git.openstack.org/openstack/devstack-plugin-pika <https://git.openstack.org/cgit/openstack/devstack-plugin-pika>`__
+devstack-plugin-sheepdog `https://git.openstack.org/openstack/devstack-plugin-sheepdog <https://git.openstack.org/cgit/openstack/devstack-plugin-sheepdog>`__
+devstack-plugin-vmax `https://git.openstack.org/openstack/devstack-plugin-vmax <https://git.openstack.org/cgit/openstack/devstack-plugin-vmax>`__
+devstack-plugin-zmq `https://git.openstack.org/openstack/devstack-plugin-zmq <https://git.openstack.org/cgit/openstack/devstack-plugin-zmq>`__
+dragonflow `https://git.openstack.org/openstack/dragonflow <https://git.openstack.org/cgit/openstack/dragonflow>`__
+drbd-devstack `https://git.openstack.org/openstack/drbd-devstack <https://git.openstack.org/cgit/openstack/drbd-devstack>`__
+ec2-api `https://git.openstack.org/openstack/ec2-api <https://git.openstack.org/cgit/openstack/ec2-api>`__
+freezer `https://git.openstack.org/openstack/freezer <https://git.openstack.org/cgit/openstack/freezer>`__
+freezer-api `https://git.openstack.org/openstack/freezer-api <https://git.openstack.org/cgit/openstack/freezer-api>`__
+freezer-tempest-plugin `https://git.openstack.org/openstack/freezer-tempest-plugin <https://git.openstack.org/cgit/openstack/freezer-tempest-plugin>`__
+freezer-web-ui `https://git.openstack.org/openstack/freezer-web-ui <https://git.openstack.org/cgit/openstack/freezer-web-ui>`__
+gce-api `https://git.openstack.org/openstack/gce-api <https://git.openstack.org/cgit/openstack/gce-api>`__
+glare `https://git.openstack.org/openstack/glare <https://git.openstack.org/cgit/openstack/glare>`__
+group-based-policy `https://git.openstack.org/openstack/group-based-policy <https://git.openstack.org/cgit/openstack/group-based-policy>`__
+gyan `https://git.openstack.org/openstack/gyan <https://git.openstack.org/cgit/openstack/gyan>`__
+heat `https://git.openstack.org/openstack/heat <https://git.openstack.org/cgit/openstack/heat>`__
+heat-dashboard `https://git.openstack.org/openstack/heat-dashboard <https://git.openstack.org/cgit/openstack/heat-dashboard>`__
+horizon-mellanox `https://git.openstack.org/openstack/horizon-mellanox <https://git.openstack.org/cgit/openstack/horizon-mellanox>`__
+ironic `https://git.openstack.org/openstack/ironic <https://git.openstack.org/cgit/openstack/ironic>`__
+ironic-inspector `https://git.openstack.org/openstack/ironic-inspector <https://git.openstack.org/cgit/openstack/ironic-inspector>`__
+ironic-staging-drivers `https://git.openstack.org/openstack/ironic-staging-drivers <https://git.openstack.org/cgit/openstack/ironic-staging-drivers>`__
+ironic-ui `https://git.openstack.org/openstack/ironic-ui <https://git.openstack.org/cgit/openstack/ironic-ui>`__
+karbor `https://git.openstack.org/openstack/karbor <https://git.openstack.org/cgit/openstack/karbor>`__
+karbor-dashboard `https://git.openstack.org/openstack/karbor-dashboard <https://git.openstack.org/cgit/openstack/karbor-dashboard>`__
+keystone `https://git.openstack.org/openstack/keystone <https://git.openstack.org/cgit/openstack/keystone>`__
+kingbird `https://git.openstack.org/openstack/kingbird <https://git.openstack.org/cgit/openstack/kingbird>`__
+kuryr-kubernetes `https://git.openstack.org/openstack/kuryr-kubernetes <https://git.openstack.org/cgit/openstack/kuryr-kubernetes>`__
+kuryr-libnetwork `https://git.openstack.org/openstack/kuryr-libnetwork <https://git.openstack.org/cgit/openstack/kuryr-libnetwork>`__
+kuryr-tempest-plugin `https://git.openstack.org/openstack/kuryr-tempest-plugin <https://git.openstack.org/cgit/openstack/kuryr-tempest-plugin>`__
+magnum `https://git.openstack.org/openstack/magnum <https://git.openstack.org/cgit/openstack/magnum>`__
+magnum-ui `https://git.openstack.org/openstack/magnum-ui <https://git.openstack.org/cgit/openstack/magnum-ui>`__
+manila `https://git.openstack.org/openstack/manila <https://git.openstack.org/cgit/openstack/manila>`__
+manila-ui `https://git.openstack.org/openstack/manila-ui <https://git.openstack.org/cgit/openstack/manila-ui>`__
+masakari `https://git.openstack.org/openstack/masakari <https://git.openstack.org/cgit/openstack/masakari>`__
+meteos `https://git.openstack.org/openstack/meteos <https://git.openstack.org/cgit/openstack/meteos>`__
+meteos-ui `https://git.openstack.org/openstack/meteos-ui <https://git.openstack.org/cgit/openstack/meteos-ui>`__
+mistral `https://git.openstack.org/openstack/mistral <https://git.openstack.org/cgit/openstack/mistral>`__
+mixmatch `https://git.openstack.org/openstack/mixmatch <https://git.openstack.org/cgit/openstack/mixmatch>`__
+mogan `https://git.openstack.org/openstack/mogan <https://git.openstack.org/cgit/openstack/mogan>`__
+mogan-ui `https://git.openstack.org/openstack/mogan-ui <https://git.openstack.org/cgit/openstack/mogan-ui>`__
+monasca-analytics `https://git.openstack.org/openstack/monasca-analytics <https://git.openstack.org/cgit/openstack/monasca-analytics>`__
+monasca-api `https://git.openstack.org/openstack/monasca-api <https://git.openstack.org/cgit/openstack/monasca-api>`__
+monasca-ceilometer `https://git.openstack.org/openstack/monasca-ceilometer <https://git.openstack.org/cgit/openstack/monasca-ceilometer>`__
+monasca-events-api `https://git.openstack.org/openstack/monasca-events-api <https://git.openstack.org/cgit/openstack/monasca-events-api>`__
+monasca-log-api `https://git.openstack.org/openstack/monasca-log-api <https://git.openstack.org/cgit/openstack/monasca-log-api>`__
+monasca-tempest-plugin `https://git.openstack.org/openstack/monasca-tempest-plugin <https://git.openstack.org/cgit/openstack/monasca-tempest-plugin>`__
+monasca-transform `https://git.openstack.org/openstack/monasca-transform <https://git.openstack.org/cgit/openstack/monasca-transform>`__
+murano `https://git.openstack.org/openstack/murano <https://git.openstack.org/cgit/openstack/murano>`__
+networking-6wind `https://git.openstack.org/openstack/networking-6wind <https://git.openstack.org/cgit/openstack/networking-6wind>`__
+networking-ansible `https://git.openstack.org/openstack/networking-ansible <https://git.openstack.org/cgit/openstack/networking-ansible>`__
+networking-arista `https://git.openstack.org/openstack/networking-arista <https://git.openstack.org/cgit/openstack/networking-arista>`__
+networking-bagpipe `https://git.openstack.org/openstack/networking-bagpipe <https://git.openstack.org/cgit/openstack/networking-bagpipe>`__
+networking-baremetal `https://git.openstack.org/openstack/networking-baremetal <https://git.openstack.org/cgit/openstack/networking-baremetal>`__
+networking-bgpvpn `https://git.openstack.org/openstack/networking-bgpvpn <https://git.openstack.org/cgit/openstack/networking-bgpvpn>`__
+networking-brocade `https://git.openstack.org/openstack/networking-brocade <https://git.openstack.org/cgit/openstack/networking-brocade>`__
+networking-calico `https://git.openstack.org/openstack/networking-calico <https://git.openstack.org/cgit/openstack/networking-calico>`__
+networking-cisco `https://git.openstack.org/openstack/networking-cisco <https://git.openstack.org/cgit/openstack/networking-cisco>`__
+networking-cumulus `https://git.openstack.org/openstack/networking-cumulus <https://git.openstack.org/cgit/openstack/networking-cumulus>`__
+networking-dpm `https://git.openstack.org/openstack/networking-dpm <https://git.openstack.org/cgit/openstack/networking-dpm>`__
+networking-fortinet `https://git.openstack.org/openstack/networking-fortinet <https://git.openstack.org/cgit/openstack/networking-fortinet>`__
+networking-generic-switch `https://git.openstack.org/openstack/networking-generic-switch <https://git.openstack.org/cgit/openstack/networking-generic-switch>`__
+networking-hpe `https://git.openstack.org/openstack/networking-hpe <https://git.openstack.org/cgit/openstack/networking-hpe>`__
+networking-huawei `https://git.openstack.org/openstack/networking-huawei <https://git.openstack.org/cgit/openstack/networking-huawei>`__
+networking-hyperv `https://git.openstack.org/openstack/networking-hyperv <https://git.openstack.org/cgit/openstack/networking-hyperv>`__
+networking-infoblox `https://git.openstack.org/openstack/networking-infoblox <https://git.openstack.org/cgit/openstack/networking-infoblox>`__
+networking-l2gw `https://git.openstack.org/openstack/networking-l2gw <https://git.openstack.org/cgit/openstack/networking-l2gw>`__
+networking-lagopus `https://git.openstack.org/openstack/networking-lagopus <https://git.openstack.org/cgit/openstack/networking-lagopus>`__
+networking-midonet `https://git.openstack.org/openstack/networking-midonet <https://git.openstack.org/cgit/openstack/networking-midonet>`__
+networking-mlnx `https://git.openstack.org/openstack/networking-mlnx <https://git.openstack.org/cgit/openstack/networking-mlnx>`__
+networking-nec `https://git.openstack.org/openstack/networking-nec <https://git.openstack.org/cgit/openstack/networking-nec>`__
+networking-odl `https://git.openstack.org/openstack/networking-odl <https://git.openstack.org/cgit/openstack/networking-odl>`__
+networking-onos `https://git.openstack.org/openstack/networking-onos <https://git.openstack.org/cgit/openstack/networking-onos>`__
+networking-opencontrail `https://git.openstack.org/openstack/networking-opencontrail <https://git.openstack.org/cgit/openstack/networking-opencontrail>`__
+networking-ovn `https://git.openstack.org/openstack/networking-ovn <https://git.openstack.org/cgit/openstack/networking-ovn>`__
+networking-ovs-dpdk `https://git.openstack.org/openstack/networking-ovs-dpdk <https://git.openstack.org/cgit/openstack/networking-ovs-dpdk>`__
+networking-plumgrid `https://git.openstack.org/openstack/networking-plumgrid <https://git.openstack.org/cgit/openstack/networking-plumgrid>`__
+networking-powervm `https://git.openstack.org/openstack/networking-powervm <https://git.openstack.org/cgit/openstack/networking-powervm>`__
+networking-sfc `https://git.openstack.org/openstack/networking-sfc <https://git.openstack.org/cgit/openstack/networking-sfc>`__
+networking-spp `https://git.openstack.org/openstack/networking-spp <https://git.openstack.org/cgit/openstack/networking-spp>`__
+networking-vpp `https://git.openstack.org/openstack/networking-vpp <https://git.openstack.org/cgit/openstack/networking-vpp>`__
+networking-vsphere `https://git.openstack.org/openstack/networking-vsphere <https://git.openstack.org/cgit/openstack/networking-vsphere>`__
+neutron `https://git.openstack.org/openstack/neutron <https://git.openstack.org/cgit/openstack/neutron>`__
+neutron-classifier `https://git.openstack.org/openstack/neutron-classifier <https://git.openstack.org/cgit/openstack/neutron-classifier>`__
+neutron-dynamic-routing `https://git.openstack.org/openstack/neutron-dynamic-routing <https://git.openstack.org/cgit/openstack/neutron-dynamic-routing>`__
+neutron-fwaas `https://git.openstack.org/openstack/neutron-fwaas <https://git.openstack.org/cgit/openstack/neutron-fwaas>`__
+neutron-fwaas-dashboard `https://git.openstack.org/openstack/neutron-fwaas-dashboard <https://git.openstack.org/cgit/openstack/neutron-fwaas-dashboard>`__
+neutron-lbaas `https://git.openstack.org/openstack/neutron-lbaas <https://git.openstack.org/cgit/openstack/neutron-lbaas>`__
+neutron-lbaas-dashboard `https://git.openstack.org/openstack/neutron-lbaas-dashboard <https://git.openstack.org/cgit/openstack/neutron-lbaas-dashboard>`__
+neutron-tempest-plugin `https://git.openstack.org/openstack/neutron-tempest-plugin <https://git.openstack.org/cgit/openstack/neutron-tempest-plugin>`__
+neutron-vpnaas `https://git.openstack.org/openstack/neutron-vpnaas <https://git.openstack.org/cgit/openstack/neutron-vpnaas>`__
+neutron-vpnaas-dashboard `https://git.openstack.org/openstack/neutron-vpnaas-dashboard <https://git.openstack.org/cgit/openstack/neutron-vpnaas-dashboard>`__
+nova-dpm `https://git.openstack.org/openstack/nova-dpm <https://git.openstack.org/cgit/openstack/nova-dpm>`__
+nova-lxd `https://git.openstack.org/openstack/nova-lxd <https://git.openstack.org/cgit/openstack/nova-lxd>`__
+nova-mksproxy `https://git.openstack.org/openstack/nova-mksproxy <https://git.openstack.org/cgit/openstack/nova-mksproxy>`__
+nova-powervm `https://git.openstack.org/openstack/nova-powervm <https://git.openstack.org/cgit/openstack/nova-powervm>`__
+oaktree `https://git.openstack.org/openstack/oaktree <https://git.openstack.org/cgit/openstack/oaktree>`__
+octavia `https://git.openstack.org/openstack/octavia <https://git.openstack.org/cgit/openstack/octavia>`__
+octavia-dashboard `https://git.openstack.org/openstack/octavia-dashboard <https://git.openstack.org/cgit/openstack/octavia-dashboard>`__
+omni `https://git.openstack.org/openstack/omni <https://git.openstack.org/cgit/openstack/omni>`__
+openstacksdk `https://git.openstack.org/openstack/openstacksdk <https://git.openstack.org/cgit/openstack/openstacksdk>`__
+os-faults `https://git.openstack.org/openstack/os-faults <https://git.openstack.org/cgit/openstack/os-faults>`__
+os-xenapi `https://git.openstack.org/openstack/os-xenapi <https://git.openstack.org/cgit/openstack/os-xenapi>`__
+osprofiler `https://git.openstack.org/openstack/osprofiler <https://git.openstack.org/cgit/openstack/osprofiler>`__
+oswin-tempest-plugin `https://git.openstack.org/openstack/oswin-tempest-plugin <https://git.openstack.org/cgit/openstack/oswin-tempest-plugin>`__
+panko `https://git.openstack.org/openstack/panko <https://git.openstack.org/cgit/openstack/panko>`__
+patrole `https://git.openstack.org/openstack/patrole <https://git.openstack.org/cgit/openstack/patrole>`__
+picasso `https://git.openstack.org/openstack/picasso <https://git.openstack.org/cgit/openstack/picasso>`__
+qinling `https://git.openstack.org/openstack/qinling <https://git.openstack.org/cgit/openstack/qinling>`__
+qinling-dashboard `https://git.openstack.org/openstack/qinling-dashboard <https://git.openstack.org/cgit/openstack/qinling-dashboard>`__
+rally `https://git.openstack.org/openstack/rally <https://git.openstack.org/cgit/openstack/rally>`__
+rally-openstack `https://git.openstack.org/openstack/rally-openstack <https://git.openstack.org/cgit/openstack/rally-openstack>`__
+rsd-virt-for-nova `https://git.openstack.org/openstack/rsd-virt-for-nova <https://git.openstack.org/cgit/openstack/rsd-virt-for-nova>`__
+sahara `https://git.openstack.org/openstack/sahara <https://git.openstack.org/cgit/openstack/sahara>`__
+sahara-dashboard `https://git.openstack.org/openstack/sahara-dashboard <https://git.openstack.org/cgit/openstack/sahara-dashboard>`__
+scalpels `https://git.openstack.org/openstack/scalpels <https://git.openstack.org/cgit/openstack/scalpels>`__
+searchlight `https://git.openstack.org/openstack/searchlight <https://git.openstack.org/cgit/openstack/searchlight>`__
+searchlight-ui `https://git.openstack.org/openstack/searchlight-ui <https://git.openstack.org/cgit/openstack/searchlight-ui>`__
+senlin `https://git.openstack.org/openstack/senlin <https://git.openstack.org/cgit/openstack/senlin>`__
+slogging `https://git.openstack.org/openstack/slogging <https://git.openstack.org/cgit/openstack/slogging>`__
+solum `https://git.openstack.org/openstack/solum <https://git.openstack.org/cgit/openstack/solum>`__
+stackube `https://git.openstack.org/openstack/stackube <https://git.openstack.org/cgit/openstack/stackube>`__
+storlets `https://git.openstack.org/openstack/storlets <https://git.openstack.org/cgit/openstack/storlets>`__
+stx-config `https://git.openstack.org/openstack/stx-config <https://git.openstack.org/cgit/openstack/stx-config>`__
+stx-fault `https://git.openstack.org/openstack/stx-fault <https://git.openstack.org/cgit/openstack/stx-fault>`__
+stx-integ `https://git.openstack.org/openstack/stx-integ <https://git.openstack.org/cgit/openstack/stx-integ>`__
+stx-metal `https://git.openstack.org/openstack/stx-metal <https://git.openstack.org/cgit/openstack/stx-metal>`__
+stx-nfv `https://git.openstack.org/openstack/stx-nfv <https://git.openstack.org/cgit/openstack/stx-nfv>`__
+stx-update `https://git.openstack.org/openstack/stx-update <https://git.openstack.org/cgit/openstack/stx-update>`__
+tacker `https://git.openstack.org/openstack/tacker <https://git.openstack.org/cgit/openstack/tacker>`__
+tap-as-a-service `https://git.openstack.org/openstack/tap-as-a-service <https://git.openstack.org/cgit/openstack/tap-as-a-service>`__
+tap-as-a-service-dashboard `https://git.openstack.org/openstack/tap-as-a-service-dashboard <https://git.openstack.org/cgit/openstack/tap-as-a-service-dashboard>`__
+tatu `https://git.openstack.org/openstack/tatu <https://git.openstack.org/cgit/openstack/tatu>`__
+telemetry-tempest-plugin `https://git.openstack.org/openstack/telemetry-tempest-plugin <https://git.openstack.org/cgit/openstack/telemetry-tempest-plugin>`__
+tobiko `https://git.openstack.org/openstack/tobiko <https://git.openstack.org/cgit/openstack/tobiko>`__
+tricircle `https://git.openstack.org/openstack/tricircle <https://git.openstack.org/cgit/openstack/tricircle>`__
+trio2o `https://git.openstack.org/openstack/trio2o <https://git.openstack.org/cgit/openstack/trio2o>`__
+trove `https://git.openstack.org/openstack/trove <https://git.openstack.org/cgit/openstack/trove>`__
+trove-dashboard `https://git.openstack.org/openstack/trove-dashboard <https://git.openstack.org/cgit/openstack/trove-dashboard>`__
+valet `https://git.openstack.org/openstack/valet <https://git.openstack.org/cgit/openstack/valet>`__
+vitrage `https://git.openstack.org/openstack/vitrage <https://git.openstack.org/cgit/openstack/vitrage>`__
+vitrage-dashboard `https://git.openstack.org/openstack/vitrage-dashboard <https://git.openstack.org/cgit/openstack/vitrage-dashboard>`__
+vitrage-tempest-plugin `https://git.openstack.org/openstack/vitrage-tempest-plugin <https://git.openstack.org/cgit/openstack/vitrage-tempest-plugin>`__
+vmware-nsx `https://git.openstack.org/openstack/vmware-nsx <https://git.openstack.org/cgit/openstack/vmware-nsx>`__
+vmware-vspc `https://git.openstack.org/openstack/vmware-vspc <https://git.openstack.org/cgit/openstack/vmware-vspc>`__
+watcher `https://git.openstack.org/openstack/watcher <https://git.openstack.org/cgit/openstack/watcher>`__
+watcher-dashboard `https://git.openstack.org/openstack/watcher-dashboard <https://git.openstack.org/cgit/openstack/watcher-dashboard>`__
+zaqar `https://git.openstack.org/openstack/zaqar <https://git.openstack.org/cgit/openstack/zaqar>`__
+zaqar-ui `https://git.openstack.org/openstack/zaqar-ui <https://git.openstack.org/cgit/openstack/zaqar-ui>`__
+zun `https://git.openstack.org/openstack/zun <https://git.openstack.org/cgit/openstack/zun>`__
+zun-ui `https://git.openstack.org/openstack/zun-ui <https://git.openstack.org/cgit/openstack/zun-ui>`__
====================================== ===
diff --git a/doc/source/plugins.rst b/doc/source/plugins.rst
index 89b9381..b1f2397 100644
--- a/doc/source/plugins.rst
+++ b/doc/source/plugins.rst
@@ -58,7 +58,7 @@
plugin's name, which is the name that should be used by users on
"enable_plugin" lines. It should generally be the last component of
the git repo path (e.g., if the plugin's repo is
- openstack/devstack-foo, then the name here should be "foo") ::
+ openstack/foo, then the name here should be "foo") ::
define_plugin <YOUR PLUGIN>
@@ -99,7 +99,7 @@
An example would be as follows::
- enable_plugin ec2-api git://git.openstack.org/openstack/ec2-api
+ enable_plugin ec2-api https://git.openstack.org/openstack/ec2-api
plugin.sh contract
==================
@@ -148,7 +148,7 @@
``devstack/settings``::
- # settings file for template
+ # settings file for template
enable_service template
@@ -277,7 +277,7 @@
# note the actual url here is somewhat irrelevant because it
# caches in nodepool, however make it a valid url for
# documentation purposes.
- export DEVSTACK_LOCAL_CONFIG="enable_plugin ec2-api git://git.openstack.org/openstack/ec2-api"
+ export DEVSTACK_LOCAL_CONFIG="enable_plugin ec2-api https://git.openstack.org/openstack/ec2-api"
See Also
========
diff --git a/doc/source/zuul_ci_jobs_migration.rst b/doc/source/zuul_ci_jobs_migration.rst
index c00f06e..633f951 100644
--- a/doc/source/zuul_ci_jobs_migration.rst
+++ b/doc/source/zuul_ci_jobs_migration.rst
@@ -102,7 +102,6 @@
tox_envlist: 'all'
devstack_localrc:
KURYR_K8S_API_PORT: 8080
- TEMPEST_PLUGINS: '/opt/stack/kuryr-tempest-plugin'
devstack_services:
kubernetes-api: true
kubernetes-controller-manager: true
@@ -114,6 +113,8 @@
kuryr-kubernetes: https://git.openstack.org/openstack/kuryr
devstack-plugin-container: https://git.openstack.org/openstack/devstack-plugin-container
neutron-lbaas: https://git.openstack.org/openstack/neutron-lbaas
+ tempest_plugins:
+ - kuryr-tempest-plugin
(...)
Job variables
diff --git a/files/rpms-suse/n-cpu b/files/rpms-suse/n-cpu
index c11e9f0..9c724cb 100644
--- a/files/rpms-suse/n-cpu
+++ b/files/rpms-suse/n-cpu
@@ -1,8 +1,9 @@
+cdrkit-cdrtools-compat # dist:sle12
cryptsetup
dosfstools
libosinfo
lvm2
-mkisofs
+mkisofs # not:sle12
open-iscsi
sg3_utils
# Stuff for diablo volumes
diff --git a/files/rpms-suse/n-novnc b/files/rpms-suse/n-novnc
deleted file mode 100644
index c8722b9..0000000
--- a/files/rpms-suse/n-novnc
+++ /dev/null
@@ -1 +0,0 @@
-python-numpy
diff --git a/files/rpms-suse/n-spice b/files/rpms-suse/n-spice
deleted file mode 100644
index c8722b9..0000000
--- a/files/rpms-suse/n-spice
+++ /dev/null
@@ -1 +0,0 @@
-python-numpy
diff --git a/files/rpms-suse/nova b/files/rpms-suse/nova
index 4103a40..1d58121 100644
--- a/files/rpms-suse/nova
+++ b/files/rpms-suse/nova
@@ -1,3 +1,4 @@
+cdrkit-cdrtools-compat # dist:sle12
conntrack-tools
curl
dnsmasq
@@ -11,7 +12,8 @@
libvirt # NOPRIME
libvirt-python # NOPRIME
mariadb # NOPRIME
-mkisofs # required for config_drive
+# mkisofs is required for config_drive
+mkisofs # not:sle12
parted
polkit
# qemu as fallback if kvm cannot be used
diff --git a/files/rpms/n-novnc b/files/rpms/n-novnc
deleted file mode 100644
index 24ce15a..0000000
--- a/files/rpms/n-novnc
+++ /dev/null
@@ -1 +0,0 @@
-numpy
diff --git a/files/rpms/n-spice b/files/rpms/n-spice
deleted file mode 100644
index 24ce15a..0000000
--- a/files/rpms/n-spice
+++ /dev/null
@@ -1 +0,0 @@
-numpy
diff --git a/files/rpms/nova b/files/rpms/nova
index 4140cd7..8d73644 100644
--- a/files/rpms/nova
+++ b/files/rpms/nova
@@ -13,7 +13,6 @@
m2crypto
mysql-devel
mysql-server # NOPRIME
-numpy # needed by websockify for spice console
parted
polkit
rabbitmq-server # NOPRIME
diff --git a/functions b/functions
index 051c816..187ad23 100644
--- a/functions
+++ b/functions
@@ -739,7 +739,7 @@
# Mount the disk with mount options to make it as efficient as possible
if ! egrep -q ${storage_data_dir} /proc/mounts; then
- sudo mount -t xfs -o loop,noatime,nodiratime,nobarrier,logbufs=8 \
+ sudo mount -t xfs -o loop,noatime,nodiratime,logbufs=8 \
${disk_image} ${storage_data_dir}
fi
}
diff --git a/functions-common b/functions-common
index af95bfb..bace9e0 100644
--- a/functions-common
+++ b/functions-common
@@ -92,7 +92,6 @@
--file $CLOUDS_YAML \
--os-cloud devstack \
--os-region-name $REGION_NAME \
- --os-identity-api-version 3 \
$CA_CERT_ARG \
--os-auth-url $KEYSTONE_SERVICE_URI \
--os-username demo \
@@ -104,7 +103,6 @@
--file $CLOUDS_YAML \
--os-cloud devstack-alt \
--os-region-name $REGION_NAME \
- --os-identity-api-version 3 \
$CA_CERT_ARG \
--os-auth-url $KEYSTONE_SERVICE_URI \
--os-username alt_demo \
@@ -116,13 +114,23 @@
--file $CLOUDS_YAML \
--os-cloud devstack-admin \
--os-region-name $REGION_NAME \
- --os-identity-api-version 3 \
$CA_CERT_ARG \
--os-auth-url $KEYSTONE_SERVICE_URI \
--os-username admin \
--os-password $ADMIN_PASSWORD \
--os-project-name admin
+ # admin with a system-scoped token -> devstack-system
+ $PYTHON $TOP_DIR/tools/update_clouds_yaml.py \
+ --file $CLOUDS_YAML \
+ --os-cloud devstack-system-admin \
+ --os-region-name $REGION_NAME \
+ $CA_CERT_ARG \
+ --os-auth-url $KEYSTONE_SERVICE_URI \
+ --os-username admin \
+ --os-password $ADMIN_PASSWORD \
+ --os-system-scope all
+
# CLean up any old clouds.yaml files we had laying around
rm -f $(eval echo ~"$STACK_USER")/.config/openstack/clouds.yaml
}
@@ -371,14 +379,14 @@
elif [[ "$os_VENDOR" =~ (Fedora) ]]; then
# For Fedora, just use 'f' and the release
DISTRO="f$os_RELEASE"
- elif [[ "$os_VENDOR" =~ (openSUSE) ]]; then
+ elif is_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. 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
+ elif is_suse_linux_enterprise; then
# just use major release
DISTRO="sle${os_RELEASE%.*}"
elif [[ "$os_VENDOR" =~ (Red.*Hat) || \
@@ -452,11 +460,30 @@
# (openSUSE, SLE).
# is_suse
function is_suse {
+ is_opensuse || is_suse_linux_enterprise
+}
+
+
+# Determine if current distribution is an openSUSE distribution
+# is_opensuse
+function is_opensuse {
if [[ -z "$os_VENDOR" ]]; then
GetOSVersion
fi
- [[ "$os_VENDOR" =~ (openSUSE) || "$os_VENDOR" == "SUSE LINUX" ]]
+ [[ "$os_VENDOR" =~ (openSUSE) ]]
+}
+
+
+# Determine if current distribution is a SUSE Linux Enterprise (SLE)
+# distribution
+# is_suse_linux_enterprise
+function is_suse_linux_enterprise {
+ if [[ -z "$os_VENDOR" ]]; then
+ GetOSVersion
+ fi
+
+ [[ "$os_VENDOR" =~ (^SUSE) ]]
}
@@ -1381,6 +1408,35 @@
zypper --non-interactive install --auto-agree-with-licenses --no-recommends "$@"
}
+# Run bindep and install packages it outputs
+#
+# Usage:
+# install_bindep <path-to-bindep.txt> [profile,profile]
+#
+# Note unlike the bindep command itself, profile(s) specified should
+# be a single, comma-separated string, no spaces.
+function install_bindep {
+ local file=$1
+ local profiles=${2:-""}
+ local pkgs
+
+ if [[ ! -f $file ]]; then
+ die $LINENO "Can not find bindep file: $file"
+ fi
+
+ # converting here makes it much easier to work with passing
+ # arguments
+ profiles=${profiles/,/ /}
+
+ # Note bindep returns 1 when packages need to be installed, so we
+ # have to ignore it's return for "-e"
+ pkgs=$($DEST/bindep-venv/bin/bindep -b --file $file $profiles || true)
+
+ if [[ -n "${pkgs}" ]]; then
+ install_package ${pkgs}
+ fi
+}
+
function write_user_unit_file {
local service=$1
local command="$2"
diff --git a/inc/ini-config b/inc/ini-config
index 6fe7788..7993682 100644
--- a/inc/ini-config
+++ b/inc/ini-config
@@ -88,17 +88,22 @@
}
# Determinate is the given option present in the INI file
-# ini_has_option config-file section option
+# ini_has_option [-sudo] config-file section option
function ini_has_option {
local xtrace
xtrace=$(set +o | grep xtrace)
set +o xtrace
+ local sudo=""
+ if [ $1 == "-sudo" ]; then
+ sudo="sudo "
+ shift
+ fi
local file=$1
local section=$2
local option=$3
local line
- line=$(sed -ne "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ p; }" "$file")
+ line=$($sudo sed -ne "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ p; }" "$file")
$xtrace
[ -n "$line" ]
}
@@ -173,8 +178,10 @@
xtrace=$(set +o | grep xtrace)
set +o xtrace
local sudo=""
+ local sudo_option=""
if [ $1 == "-sudo" ]; then
sudo="sudo "
+ sudo_option="-sudo "
shift
fi
local file=$1
@@ -187,11 +194,11 @@
return
fi
- if ! grep -q "^\[$section\]" "$file" 2>/dev/null; then
+ if ! $sudo grep -q "^\[$section\]" "$file" 2>/dev/null; then
# Add section at the end
echo -e "\n[$section]" | $sudo tee --append "$file" > /dev/null
fi
- if ! ini_has_option "$file" "$section" "$option"; then
+ if ! ini_has_option $sudo_option "$file" "$section" "$option"; then
# Add it
$sudo sed -i -e "/^\[$section\]/ a\\
$option = $value
@@ -228,7 +235,7 @@
# the reverse order. Do a reverse here to keep the original order.
values="$v ${values}"
done
- if ! grep -q "^\[$section\]" "$file"; then
+ if ! $sudo grep -q "^\[$section\]" "$file"; then
# Add section at the end
echo -e "\n[$section]" | $sudo tee --append "$file" > /dev/null
else
diff --git a/inc/python b/inc/python
index 5fb7245..19e1228 100644
--- a/inc/python
+++ b/inc/python
@@ -49,15 +49,9 @@
fi
$xtrace
- 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"
- elif is_fedora || is_suse; then
- echo "/usr/bin"
- else
- echo "/usr/local/bin"
- fi
+ local PYTHON_PATH=/usr/local/bin
+ ( is_fedora && ! python3_enabled ) || is_suse && PYTHON_PATH=/usr/bin
+ echo $PYTHON_PATH
}
# Wrapper for ``pip install`` that only installs versions of libraries
@@ -87,41 +81,12 @@
pip_install $clean_name[$extras]
}
-# Determine the python versions supported by a package
-function get_python_versions_for_package {
- local name=$1
- cd $name && python setup.py --classifiers \
- | grep 'Language' | cut -f5 -d: | grep '\.' | tr '\n' ' '
-}
-
-# Check for python3 classifier in local directory
-function check_python3_support_for_package_local {
- local name=$1
- cd $name
- set +e
- classifier=$(python setup.py --classifiers \
- | grep 'Programming Language :: Python :: 3$')
- set -e
- echo $classifier
-}
-
-# Check for python3 classifier on pypi
-function check_python3_support_for_package_remote {
- local name=$1
- set +e
- classifier=$(curl -s -L "https://pypi.python.org/pypi/$name/json" \
- | grep '"Programming Language :: Python :: 3"')
- set -e
- echo $classifier
-}
-
-# python3_enabled_for() checks if the service(s) specified as arguments are
-# enabled by the user in ``ENABLED_PYTHON3_PACKAGES``.
+# python3_enabled_for() assumes the service(s) specified as arguments are
+# enabled for python 3 unless explicitly disabled. See python3_disabled_for().
#
# Multiple services specified as arguments are ``OR``'ed together; the test
# is a short-circuit boolean, i.e it returns on the first match.
#
-# Uses global ``ENABLED_PYTHON3_PACKAGES``
# python3_enabled_for dir [dir ...]
function python3_enabled_for {
local xtrace
@@ -132,7 +97,9 @@
local dirs=$@
local dir
for dir in ${dirs}; do
- [[ ,${ENABLED_PYTHON3_PACKAGES}, =~ ,${dir}, ]] && enabled=0
+ if ! python3_disabled_for "${dir}"; then
+ enabled=0
+ fi
done
$xtrace
@@ -163,42 +130,29 @@
return $enabled
}
-# enable_python3_package() adds the repositories passed as argument to the
-# ``ENABLED_PYTHON3_PACKAGES`` list, if they are not already present.
+# enable_python3_package() -- no-op for backwards compatibility
#
# For example:
# enable_python3_package nova
#
-# Uses global ``ENABLED_PYTHON3_PACKAGES``
# enable_python3_package dir [dir ...]
function enable_python3_package {
local xtrace
xtrace=$(set +o | grep xtrace)
set +o xtrace
- local tmpsvcs="${ENABLED_PYTHON3_PACKAGES}"
- local python3
- for dir in $@; do
- if [[ ,${DISABLED_PYTHON3_PACKAGES}, =~ ,${dir}, ]]; then
- warn $LINENO "Attempt to enable_python3_package ${dir} when it has been disabled"
- continue
- fi
- if ! python3_enabled_for $dir; then
- tmpsvcs+=",$dir"
- fi
- done
- ENABLED_PYTHON3_PACKAGES=$(_cleanup_service_list "$tmpsvcs")
+ echo "It is no longer necessary to call enable_python3_package()."
$xtrace
}
-# disable_python3_package() prepares the services passed as argument to be
-# removed from the ``ENABLED_PYTHON3_PACKAGES`` list, if they are present.
+# disable_python3_package() adds the services passed as argument to
+# the ``DISABLED_PYTHON3_PACKAGES`` list.
#
# For example:
# disable_python3_package swift
#
-# Uses globals ``ENABLED_PYTHON3_PACKAGES`` and ``DISABLED_PYTHON3_PACKAGES``
+# Uses global ``DISABLED_PYTHON3_PACKAGES``
# disable_python3_package dir [dir ...]
function disable_python3_package {
local xtrace
@@ -206,16 +160,11 @@
set +o xtrace
local disabled_svcs="${DISABLED_PYTHON3_PACKAGES}"
- local enabled_svcs=",${ENABLED_PYTHON3_PACKAGES},"
local dir
for dir in $@; do
disabled_svcs+=",$dir"
- if python3_enabled_for $dir; then
- enabled_svcs=${enabled_svcs//,$dir,/,}
- fi
done
DISABLED_PYTHON3_PACKAGES=$(_cleanup_service_list "$disabled_svcs")
- ENABLED_PYTHON3_PACKAGES=$(_cleanup_service_list "$enabled_svcs")
$xtrace
}
@@ -282,48 +231,20 @@
cmd_pip=$(get_pip_command $PYTHON2_VERSION)
local sudo_pip="sudo -H"
if python3_enabled; then
- # Look at the package classifiers to find the python
- # versions supported, and if we find the version of
- # python3 we've been told to use, use that instead of the
- # default pip
- local python_versions
-
# Special case some services that have experimental
# support for python3 in progress, but don't claim support
# in their classifier
echo "Check python version for : $package_dir"
if python3_disabled_for ${package_dir##*/}; then
echo "Explicitly using $PYTHON2_VERSION version to install $package_dir based on DISABLED_PYTHON3_PACKAGES"
- elif python3_enabled_for ${package_dir##*/}; then
- echo "Explicitly using $PYTHON3_VERSION version to install $package_dir based on ENABLED_PYTHON3_PACKAGES"
+ else
+ # For everything that is not explicitly blacklisted with
+ # DISABLED_PYTHON3_PACKAGES, assume it supports python3
+ # and we will let pip sort out the install, regardless of
+ # the package being local or remote.
+ echo "Using $PYTHON3_VERSION version to install $package_dir based on default behavior"
sudo_pip="$sudo_pip LC_ALL=en_US.UTF-8"
cmd_pip=$(get_pip_command $PYTHON3_VERSION)
- elif [[ -d "$package_dir" ]]; then
- python_versions=$(get_python_versions_for_package $package_dir)
- if [[ $python_versions =~ $PYTHON3_VERSION ]]; then
- echo "Automatically using $PYTHON3_VERSION version to install $package_dir based on classifiers"
- sudo_pip="$sudo_pip LC_ALL=en_US.UTF-8"
- cmd_pip=$(get_pip_command $PYTHON3_VERSION)
- else
- # The package may not have yet advertised python3.5
- # support so check for just python3 classifier and log
- # a warning.
- python3_classifier=$(check_python3_support_for_package_local $package_dir)
- if [[ ! -z "$python3_classifier" ]]; then
- echo "Automatically using $PYTHON3_VERSION version to install $package_dir based on local package settings"
- sudo_pip="$sudo_pip LC_ALL=en_US.UTF-8"
- cmd_pip=$(get_pip_command $PYTHON3_VERSION)
- fi
- fi
- else
- # Check pypi as we don't have the package on disk
- package=$(echo $package_dir | grep -o '^[.a-zA-Z0-9_-]*')
- python3_classifier=$(check_python3_support_for_package_remote $package)
- if [[ ! -z "$python3_classifier" ]]; then
- echo "Automatically using $PYTHON3_VERSION version to install $package based on remote package settings"
- sudo_pip="$sudo_pip LC_ALL=en_US.UTF-8"
- cmd_pip=$(get_pip_command $PYTHON3_VERSION)
- fi
fi
fi
fi
@@ -445,7 +366,14 @@
# another project.
#
# use this for non namespaced libraries
+#
+# setup_dev_lib [-bindep] <name>
function setup_dev_lib {
+ local bindep
+ if [[ $1 == -bindep* ]]; then
+ bindep="${1}"
+ shift
+ fi
local name=$1
local dir=${GITDIR[$name]}
if python3_enabled; then
@@ -455,10 +383,10 @@
# of Python.
echo "Installing $name again without Python 3 enabled"
USE_PYTHON3=False
- setup_develop $dir
+ setup_develop $bindep $dir
USE_PYTHON3=True
fi
- setup_develop $dir
+ setup_develop $bindep $dir
}
# this should be used if you want to install globally, all libraries should
@@ -469,11 +397,17 @@
# extras: comma-separated list of optional dependencies to install
# (e.g., ldap,memcache).
# See https://docs.openstack.org/pbr/latest/user/using.html#extra-requirements
+# bindep: Set "-bindep" as first argument to install bindep.txt packages
# The command is like "pip install <project_dir>[<extras>]"
function setup_install {
+ local bindep
+ if [[ $1 == -bindep* ]]; then
+ bindep="${1}"
+ shift
+ fi
local project_dir=$1
local extras=$2
- _setup_package_with_constraints_edit $project_dir "" $extras
+ _setup_package_with_constraints_edit $bindep $project_dir "" $extras
}
# this should be used for projects which run services, like all services
@@ -485,9 +419,14 @@
# See https://docs.openstack.org/pbr/latest/user/using.html#extra-requirements
# The command is like "pip install -e <project_dir>[<extras>]"
function setup_develop {
+ local bindep
+ if [[ $1 == -bindep* ]]; then
+ bindep="${1}"
+ shift
+ fi
local project_dir=$1
local extras=$2
- _setup_package_with_constraints_edit $project_dir -e $extras
+ _setup_package_with_constraints_edit $bindep $project_dir -e $extras
}
# ``pip install -e`` the package, which processes the dependencies
@@ -506,6 +445,11 @@
# See https://docs.openstack.org/pbr/latest/user/using.html#extra-requirements
# The command is like "pip install <flags> <project_dir>[<extras>]"
function _setup_package_with_constraints_edit {
+ local bindep
+ if [[ $1 == -bindep* ]]; then
+ bindep="${1}"
+ shift
+ fi
local project_dir=$1
local flags=$2
local extras=$3
@@ -526,7 +470,7 @@
"$flags file://$project_dir#egg=$name"
fi
- setup_package $project_dir "$flags" $extras
+ setup_package $bindep $project_dir "$flags" $extras
# If this project is in LIBS_FROM_GIT, verify it was actually installed
# correctly. This helps catch errors caused by constraints mismatches.
@@ -538,17 +482,30 @@
}
# ``pip install -e`` the package, which processes the dependencies
-# using pip before running `setup.py develop`
+# using pip before running `setup.py develop`. The command is like
+# "pip install <flags> <project_dir>[<extras>]"
#
# Uses globals ``STACK_USER``
-# setup_package project_dir [flags] [extras]
-# project_dir: directory of project repo (e.g., /opt/stack/keystone)
-# flags: pip CLI options/flags
-# extras: comma-separated list of optional dependencies to install
-# (e.g., ldap,memcache).
-# See https://docs.openstack.org/pbr/latest/user/using.html#extra-requirements
-# The command is like "pip install <flags> <project_dir>[<extras>]"
+#
+# Usage:
+# setup_package [-bindep[=profile,profile]] <project_dir> <flags> [extras]
+#
+# -bindep : Use bindep to install dependencies; select extra profiles
+# as comma separated arguments after "="
+# project_dir : directory of project repo (e.g., /opt/stack/keystone)
+# flags : pip CLI options/flags
+# extras : comma-separated list of optional dependencies to install
+# (e.g., ldap,memcache).
+# See https://docs.openstack.org/pbr/latest/user/using.html#extra-requirements
function setup_package {
+ local bindep=0
+ local bindep_flag=""
+ local bindep_profiles=""
+ if [[ $1 == -bindep* ]]; then
+ bindep=1
+ IFS="=" read bindep_flag bindep_profiles <<< ${1}
+ shift
+ fi
local project_dir=$1
local flags=$2
local extras=$3
@@ -564,6 +521,11 @@
extras="[$extras]"
fi
+ # install any bindep packages
+ if [[ $bindep == 1 ]]; then
+ install_bindep $project_dir/bindep.txt $bindep_profiles
+ fi
+
pip_install $flags "$project_dir$extras"
# ensure that further actions can do things like setup.py sdist
if [[ "$flags" == "-e" ]]; then
diff --git a/lib/cinder b/lib/cinder
index 76bf928..047b25b 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -349,18 +349,12 @@
# block-storage is the official service type
get_or_create_service "cinder" "block-storage" "Cinder Volume Service"
- get_or_create_service "cinder" "volume" "Cinder Volume Service"
if [ "$CINDER_USE_MOD_WSGI" == "False" ]; then
get_or_create_endpoint \
"block-storage" \
"$REGION_NAME" \
"$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v3/\$(project_id)s"
- get_or_create_endpoint \
- "volume" \
- "$REGION_NAME" \
- "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v1/\$(project_id)s"
-
get_or_create_service "cinderv2" "volumev2" "Cinder Volume Service V2"
get_or_create_endpoint \
"volumev2" \
@@ -378,11 +372,6 @@
"$REGION_NAME" \
"$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST/volume/v3/\$(project_id)s"
- get_or_create_endpoint \
- "volume" \
- "$REGION_NAME" \
- "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST/volume/v1/\$(project_id)s"
-
get_or_create_service "cinderv2" "volumev2" "Cinder Volume Service V2"
get_or_create_endpoint \
"volumev2" \
@@ -445,7 +434,14 @@
if [[ "$CINDER_ISCSI_HELPER" == "tgtadm" ]]; then
install_package tgt
elif [[ "$CINDER_ISCSI_HELPER" == "lioadm" ]]; then
- install_package targetcli
+ if [[ ${DISTRO} == "bionic" ]]; then
+ # TODO(frickler): Workaround for https://launchpad.net/bugs/1819819
+ sudo mkdir -p /etc/target
+
+ install_package targetcli-fb
+ else
+ install_package targetcli
+ fi
fi
}
diff --git a/lib/databases/mysql b/lib/databases/mysql
index ac0c083..4d0f5f3 100644
--- a/lib/databases/mysql
+++ b/lib/databases/mysql
@@ -16,7 +16,13 @@
register_database mysql
MYSQL_SERVICE_NAME=mysql
-if is_suse || is_fedora && ! is_oraclelinux; then
+if is_fedora && ! is_oraclelinux; then
+ MYSQL_SERVICE_NAME=mariadb
+elif is_suse && systemctl list-unit-files | grep -q 'mariadb\.service'; then
+ # Older mariadb packages on SLES 12 provided mysql.service. The
+ # newer ones on SLES 12 and 15 use mariadb.service; they also
+ # provide a mysql.service symlink for backwards-compatibility, but
+ # let's not rely on that.
MYSQL_SERVICE_NAME=mariadb
fi
diff --git a/lib/etcd3 b/lib/etcd3
index 26d07fd..4f3a7a4 100644
--- a/lib/etcd3
+++ b/lib/etcd3
@@ -27,6 +27,10 @@
ETCD_DATA_DIR="$DATA_DIR/etcd"
ETCD_SYSTEMD_SERVICE="devstack@etcd.service"
ETCD_BIN_DIR="$DEST/bin"
+# Option below will mount ETCD_DATA_DIR as ramdisk, which is useful to run
+# etcd-heavy services in the gate VM's, e.g. Kubernetes.
+ETCD_USE_RAMDISK=$(trueorfalse True ETCD_USE_RAMDISK)
+ETCD_RAMDISK_MB=${ETCD_RAMDISK_MB:-512}
if is_ubuntu ; then
UBUNTU_RELEASE_BASE_NUM=`lsb_release -r | awk '{print $2}' | cut -d '.' -f 1`
@@ -46,6 +50,9 @@
cmd+=" --listen-peer-urls http://0.0.0.0:$ETCD_PEER_PORT "
fi
cmd+=" --listen-client-urls http://$SERVICE_HOST:$ETCD_PORT"
+ if [ "$ENABLE_DEBUG_LOG_LEVEL" == "True" ]; then
+ cmd+=" --debug"
+ fi
local unitfile="$SYSTEMD_DIR/$ETCD_SYSTEMD_SERVICE"
write_user_unit_file $ETCD_SYSTEMD_SERVICE "$cmd" "" "root"
@@ -86,6 +93,9 @@
$SYSTEMCTL daemon-reload
+ if [[ "$ETCD_USE_RAMDISK" == "True" ]]; then
+ sudo umount $ETCD_DATA_DIR
+ fi
sudo rm -rf $ETCD_DATA_DIR
}
@@ -95,6 +105,9 @@
# Create the necessary directories
sudo mkdir -p $ETCD_BIN_DIR
sudo mkdir -p $ETCD_DATA_DIR
+ if [[ "$ETCD_USE_RAMDISK" == "True" ]]; then
+ sudo mount -t tmpfs -o nodev,nosuid,size=${ETCD_RAMDISK_MB}M tmpfs $ETCD_DATA_DIR
+ fi
# Download and cache the etcd tgz for subsequent use
local etcd_file
diff --git a/lib/glance b/lib/glance
index 94f6a22..65487cb 100644
--- a/lib/glance
+++ b/lib/glance
@@ -236,8 +236,8 @@
CINDER_SERVICE_HOST=${CINDER_SERVICE_HOST:-$SERVICE_HOST}
CINDER_SERVICE_PORT=${CINDER_SERVICE_PORT:-8776}
- iniset $GLANCE_API_CONF DEFAULT cinder_endpoint_template "https://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v1/%(project_id)s"
- iniset $GLANCE_CACHE_CONF DEFAULT cinder_endpoint_template "https://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v1/%(project_id)s"
+ iniset $GLANCE_API_CONF DEFAULT cinder_endpoint_template "https://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v3/%(project_id)s"
+ iniset $GLANCE_CACHE_CONF DEFAULT cinder_endpoint_template "https://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v3/%(project_id)s"
fi
if [[ "$WSGI_MODE" == "uwsgi" ]]; then
@@ -345,7 +345,7 @@
if [[ "$WSGI_MODE" == "uwsgi" ]]; then
run_process g-api "$GLANCE_BIN_DIR/uwsgi --procname-prefix glance-api --ini $GLANCE_UWSGI_CONF"
else
- run_process g-api "$GLANCE_BIN_DIR/glance-api --config-file=$GLANCE_CONF_DIR/glance-api.conf"
+ run_process g-api "$GLANCE_BIN_DIR/glance-api --config-dir=$GLANCE_CONF_DIR"
fi
echo "Waiting for g-api ($GLANCE_SERVICE_HOST) to start..."
diff --git a/lib/neutron b/lib/neutron
index 62f7366..1066d8e 100644
--- a/lib/neutron
+++ b/lib/neutron
@@ -33,7 +33,7 @@
# - True : Run neutron under uwsgi
# TODO(annp): Switching to uwsgi in next cycle if things turn out to be stable
# enough
-NEUTRON_DEPLOY_MOD_WSGI=${NEUTRON_DEPLOY_MOD_WSGI:-False}
+NEUTRON_DEPLOY_MOD_WSGI=$(trueorfalse False NEUTRON_DEPLOY_MOD_WSGI)
NEUTRON_AGENT=${NEUTRON_AGENT:-openvswitch}
NEUTRON_DIR=$DEST/neutron
NEUTRON_AUTH_CACHE_DIR=${NEUTRON_AUTH_CACHE_DIR:-/var/cache/neutron}
@@ -95,9 +95,6 @@
NEUTRON_ROOTWRAP_CMD="$NEUTRON_ROOTWRAP $NEUTRON_ROOTWRAP_CONF_FILE"
NEUTRON_ROOTWRAP_DAEMON_CMD="$NEUTRON_ROOTWRAP-daemon $NEUTRON_ROOTWRAP_CONF_FILE"
-# This is needed because _neutron_ovs_base_configure_l3_agent will set
-# external_network_bridge
-Q_USE_PROVIDERNET_FOR_PUBLIC=${Q_USE_PROVIDERNET_FOR_PUBLIC:-True}
# This is needed because _neutron_ovs_base_configure_l3_agent uses it to create
# an external network bridge
PUBLIC_BRIDGE=${PUBLIC_BRIDGE:-br-ex}
diff --git a/lib/neutron-legacy b/lib/neutron-legacy
index 2fdb6db..8257115 100644
--- a/lib/neutron-legacy
+++ b/lib/neutron-legacy
@@ -91,7 +91,7 @@
# - True : Run neutron under uwsgi
# TODO(annp): Switching to uwsgi in next cycle if things turn out to be stable
# enough
-NEUTRON_DEPLOY_MOD_WSGI=${NEUTRON_DEPLOY_MOD_WSGI:-False}
+NEUTRON_DEPLOY_MOD_WSGI=$(trueorfalse False NEUTRON_DEPLOY_MOD_WSGI)
NEUTRON_UWSGI_CONF=$NEUTRON_CONF_DIR/neutron-api-uwsgi.ini
diff --git a/lib/neutron_plugins/linuxbridge_agent b/lib/neutron_plugins/linuxbridge_agent
index f2302e3..fa3f862 100644
--- a/lib/neutron_plugins/linuxbridge_agent
+++ b/lib/neutron_plugins/linuxbridge_agent
@@ -8,21 +8,23 @@
set +o xtrace
function neutron_lb_cleanup {
- sudo ip link set $PUBLIC_BRIDGE down
- sudo brctl delbr $PUBLIC_BRIDGE
+ sudo ip link delete $PUBLIC_BRIDGE
+ bridge_list=`ls /sys/class/net/*/bridge/bridge_id 2>/dev/null | cut -f5 -d/`
+ if [[ -z "$bridge_list" ]]; then
+ return
+ fi
if [[ "$Q_ML2_TENANT_NETWORK_TYPE" = "vxlan" ]]; then
- for port in $(sudo brctl show | grep -o -e [a-zA-Z\-]*tap[0-9a-f\-]* -e vxlan-[0-9a-f\-]*); do
+ for port in $(echo $bridge_list | grep -o -e [a-zA-Z\-]*tap[0-9a-f\-]* -e vxlan-[0-9a-f\-]*); do
sudo ip link delete $port
done
elif [[ "$Q_ML2_TENANT_NETWORK_TYPE" = "vlan" ]]; then
- for port in $(sudo brctl show | grep -o -e [a-zA-Z\-]*tap[0-9a-f\-]* -e ${LB_PHYSICAL_INTERFACE}\.[0-9a-f\-]*); do
+ for port in $(echo $bridge_list | grep -o -e [a-zA-Z\-]*tap[0-9a-f\-]* -e ${LB_PHYSICAL_INTERFACE}\.[0-9a-f\-]*); do
sudo ip link delete $port
done
fi
- for bridge in $(sudo brctl show |grep -o -e brq[0-9a-f\-]*); do
- sudo ip link set $bridge down
- sudo brctl delbr $bridge
+ for bridge in $(echo $bridge_list |grep -o -e brq[0-9a-f\-]*); do
+ sudo ip link delete $bridge
done
}
diff --git a/lib/neutron_plugins/ovs_base b/lib/neutron_plugins/ovs_base
index 523024e..2e63fe3 100644
--- a/lib/neutron_plugins/ovs_base
+++ b/lib/neutron_plugins/ovs_base
@@ -69,7 +69,7 @@
restart_service openvswitch
sudo systemctl enable openvswitch
elif is_suse; then
- if [[ $DISTRO == "sle12" ]] && [[ $os_RELEASE -lt 12.2 ]]; then
+ if [[ $DISTRO == "sle12" ]] && vercmp "$os_RELEASE" "<" "12.2" ; then
restart_service openvswitch-switch
else
# workaround for https://bugzilla.suse.com/show_bug.cgi?id=1085971
@@ -96,10 +96,6 @@
}
function _neutron_ovs_base_configure_l3_agent {
- if [ "$Q_USE_PROVIDERNET_FOR_PUBLIC" != "True" ]; then
- iniset $Q_L3_CONF_FILE DEFAULT external_network_bridge $PUBLIC_BRIDGE
- fi
-
neutron-ovs-cleanup --config-file $NEUTRON_CONF
if [[ "$Q_USE_PUBLIC_VETH" = "True" ]]; then
ip link show $Q_PUBLIC_VETH_INT > /dev/null 2>&1 ||
diff --git a/lib/nova b/lib/nova
index d1d0b3c..dee798c 100644
--- a/lib/nova
+++ b/lib/nova
@@ -183,6 +183,10 @@
# and Glance.
NOVA_USE_SERVICE_TOKEN=$(trueorfalse False NOVA_USE_SERVICE_TOKEN)
+# Enable debugging levels for iscsid service (goes from 0-8)
+ISCSID_DEBUG=$(trueorfalse False ISCSID_DEBUG)
+ISCSID_DEBUG_LEVEL=${ISCSID_DEBUG_LEVEL:-4}
+
# Functions
# ---------
@@ -327,10 +331,22 @@
sudo chown -R $STACK_USER $NOVA_INSTANCES_PATH
fi
fi
- if is_suse; then
- # iscsid is not started by default
- start_service iscsid
+
+ if [[ ${ISCSID_DEBUG} == "True" ]]; then
+ # Install an override that starts iscsid with debugging
+ # enabled.
+ cat > /tmp/iscsid.override <<EOF
+[Service]
+ExecStart=
+ExecStart=/usr/sbin/iscsid -d${ISCSID_DEBUG_LEVEL}
+EOF
+ sudo mkdir -p /etc/systemd/system/iscsid.service.d
+ sudo mv /tmp/iscsid.override /etc/systemd/system/iscsid.service.d/override.conf
+ sudo systemctl daemon-reload
fi
+
+ # ensure that iscsid is started, even when disabled by default
+ restart_service iscsid
fi
# Rebuild the config file from scratch
@@ -597,11 +613,35 @@
fi
}
+# Configure access to placement from a nova service, usually
+# compute, but sometimes conductor.
+function configure_placement_nova_compute {
+ # Use the provided config file path or default to $NOVA_CONF.
+ local conf=${1:-$NOVA_CONF}
+ iniset $conf placement auth_type "password"
+ iniset $conf placement auth_url "$KEYSTONE_SERVICE_URI"
+ iniset $conf placement username placement
+ iniset $conf placement password "$SERVICE_PASSWORD"
+ iniset $conf placement user_domain_name "$SERVICE_DOMAIN_NAME"
+ iniset $conf placement project_name "$SERVICE_TENANT_NAME"
+ iniset $conf placement project_domain_name "$SERVICE_DOMAIN_NAME"
+ iniset $conf placement region_name "$REGION_NAME"
+}
+
function configure_console_compute {
# All nova-compute workers need to know the vnc configuration options
# These settings don't hurt anything if n-xvnc and n-novnc are disabled
if is_service_enabled n-cpu; then
- NOVNCPROXY_URL=${NOVNCPROXY_URL:-"http://$SERVICE_HOST:6080/vnc_auto.html"}
+ if [ "$NOVNC_FROM_PACKAGE" == "True" ]; then
+ # Use the old URL when installing novnc packages.
+ NOVNCPROXY_URL=${NOVNCPROXY_URL:-"http://$SERVICE_HOST:6080/vnc_auto.html"}
+ elif vercmp ${NOVNC_BRANCH} "<" "1.0.0"; then
+ # Use the old URL when installing older novnc source.
+ NOVNCPROXY_URL=${NOVNCPROXY_URL:-"http://$SERVICE_HOST:6080/vnc_auto.html"}
+ else
+ # Use the new URL when building >=v1.0.0 from source.
+ NOVNCPROXY_URL=${NOVNCPROXY_URL:-"http://$SERVICE_HOST:6080/vnc_lite.html"}
+ fi
iniset $NOVA_CPU_CONF vnc novncproxy_base_url "$NOVNCPROXY_URL"
XVPVNCPROXY_URL=${XVPVNCPROXY_URL:-"http://$SERVICE_HOST:6081/console"}
iniset $NOVA_CPU_CONF vnc xvpvncproxy_base_url "$XVPVNCPROXY_URL"
@@ -652,6 +692,22 @@
sudo mkdir -p /etc/pki/nova-novnc
deploy_int_CA /etc/pki/nova-novnc/ca-cert.pem
deploy_int_cert /etc/pki/nova-novnc/client-cert.pem /etc/pki/nova-novnc/client-key.pem
+ # OpenSSL 1.1.0 generates the key file with permissions: 600, by
+ # default, and the deploy_int* methods use 'sudo cp' to copy the
+ # files, making them owned by root:root.
+ # Change ownership of everything under /etc/pki/nova-novnc to
+ # $STACK_USER:$(id -g ${STACK_USER}) so that $STACK_USER can read
+ # the key file.
+ sudo chown -R $STACK_USER:$(id -g ${STACK_USER}) /etc/pki/nova-novnc
+ # This is needed to enable TLS in the proxy itself, example log:
+ # WebSocket server settings:
+ # - Listen on 0.0.0.0:6080
+ # - Flash security policy server
+ # - Web server (no directory listings). Web root: /usr/share/novnc
+ # - SSL/TLS support
+ # - proxying from 0.0.0.0:6080 to None:None
+ iniset $conf DEFAULT key "/etc/pki/nova-novnc/client-key.pem"
+ iniset $conf DEFAULT cert "/etc/pki/nova-novnc/client-cert.pem"
fi
fi
@@ -897,25 +953,26 @@
local compute_cell_conf=$NOVA_CONF
fi
+ cp $compute_cell_conf $NOVA_CPU_CONF
+
if [[ "${CELLSV2_SETUP}" == "singleconductor" ]]; then
# NOTE(danms): Grenade doesn't setup multi-cell rabbit, so
# skip these bits and use the normal config.
- NOVA_CPU_CONF=$compute_cell_conf
echo "Skipping multi-cell conductor fleet setup"
else
# "${CELLSV2_SETUP}" is "superconductor"
- cp $compute_cell_conf $NOVA_CPU_CONF
# FIXME(danms): Should this be configurable?
iniset $NOVA_CPU_CONF workarounds disable_group_policy_check_upcall True
# Since the nova-compute service cannot reach nova-scheduler over
# 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
+ # Make sure we nuke any database config
+ inidelete $NOVA_CPU_CONF database connection
+ inidelete $NOVA_CPU_CONF api_database connection
+
# Console proxies were configured earlier in create_nova_conf. Now that the
# nova-cpu.conf has been created, configure the console settings required
# by the compute process.
@@ -1153,7 +1210,7 @@
if is_service_enabled n-api; then
if ! openstack --os-region-name="$REGION_NAME" flavor list | grep -q ds512M; then
# Note that danms hates these flavors and apologizes for sdague
- openstack --os-region-name="$REGION_NAME" flavor create --id c1 --ram 256 --disk 0 --vcpus 1 cirros256
+ openstack --os-region-name="$REGION_NAME" flavor create --id c1 --ram 256 --disk 1 --vcpus 1 cirros256
openstack --os-region-name="$REGION_NAME" flavor create --id d1 --ram 512 --disk 5 --vcpus 1 ds512M
openstack --os-region-name="$REGION_NAME" flavor create --id d2 --ram 1024 --disk 10 --vcpus 1 ds1G
openstack --os-region-name="$REGION_NAME" flavor create --id d3 --ram 2048 --disk 10 --vcpus 2 ds2G
diff --git a/lib/nova_plugins/functions-libvirt b/lib/nova_plugins/functions-libvirt
index fcb4777..4639869 100644
--- a/lib/nova_plugins/functions-libvirt
+++ b/lib/nova_plugins/functions-libvirt
@@ -155,9 +155,15 @@
echo "vnc_tls_x509_verify = 1" | sudo tee -a $QEMU_CONF
sudo mkdir -p /etc/pki/libvirt-vnc
- sudo chown libvirt-qemu:libvirt-qemu /etc/pki/libvirt-vnc
deploy_int_CA /etc/pki/libvirt-vnc/ca-cert.pem
deploy_int_cert /etc/pki/libvirt-vnc/server-cert.pem /etc/pki/libvirt-vnc/server-key.pem
+ # OpenSSL 1.1.0 generates the key file with permissions: 600, by
+ # default and the deploy_int* methods use 'sudo cp' to copy the
+ # files, making them owned by root:root.
+ # Change ownership of everything under /etc/pki/libvirt-vnc to
+ # libvirt-qemu:libvirt-qemu so that libvirt-qemu can read the key
+ # file.
+ sudo chown -R libvirt-qemu:libvirt-qemu /etc/pki/libvirt-vnc
fi
fi
diff --git a/lib/placement b/lib/placement
index da69e39..a89cd26 100644
--- a/lib/placement
+++ b/lib/placement
@@ -93,19 +93,6 @@
" -i $placement_api_apache_conf
}
-function configure_placement_nova_compute {
- # Use the provided config file path or default to $NOVA_CONF.
- local conf=${1:-$NOVA_CONF}
- iniset $conf placement auth_type "password"
- iniset $conf placement auth_url "$KEYSTONE_SERVICE_URI"
- iniset $conf placement username placement
- iniset $conf placement password "$SERVICE_PASSWORD"
- iniset $conf placement user_domain_name "$SERVICE_DOMAIN_NAME"
- iniset $conf placement project_name "$SERVICE_TENANT_NAME"
- iniset $conf placement project_domain_name "$SERVICE_DOMAIN_NAME"
- iniset $conf placement auth_strategy $PLACEMENT_AUTH_STRATEGY
-}
-
# create_placement_conf() - Write config
function create_placement_conf {
rm -f $PLACEMENT_CONF
diff --git a/lib/swift b/lib/swift
index 3b3e608..e2ee0cb 100644
--- a/lib/swift
+++ b/lib/swift
@@ -607,7 +607,7 @@
# Mount the disk with mount options to make it as efficient as possible
mkdir -p ${SWIFT_DATA_DIR}/drives/sdb1
if ! egrep -q ${SWIFT_DATA_DIR}/drives/sdb1 /proc/mounts; then
- sudo mount -t xfs -o loop,noatime,nodiratime,nobarrier,logbufs=8 \
+ sudo mount -t xfs -o loop,noatime,nodiratime,logbufs=8 \
${SWIFT_DISK_IMAGE} ${SWIFT_DATA_DIR}/drives/sdb1
fi
diff --git a/lib/tcpdump b/lib/tcpdump
new file mode 100644
index 0000000..16e8269
--- /dev/null
+++ b/lib/tcpdump
@@ -0,0 +1,43 @@
+#!/bin/bash
+#
+# lib/tcpdump
+# Functions to start and stop a tcpdump
+
+# Dependencies:
+#
+# - ``functions`` file
+
+# ``stack.sh`` calls the entry points in this order:
+#
+# - start_tcpdump
+# - stop_tcpdump
+
+# Save trace setting
+_XTRACE_TCPDUMP=$(set +o | grep xtrace)
+set +o xtrace
+
+TCPDUMP_OUTPUT=${TCPDUMP_OUTPUT:-$LOGDIR/tcpdump.pcap}
+
+# e.g. for iscsi
+# "-i any tcp port 3260"
+TCPDUMP_ARGS=${TCPDUMP_ARGS:-""}
+
+# start_tcpdump() - Start running processes
+function start_tcpdump {
+ # Run a tcpdump with given arguments and save the packet capture
+ if is_service_enabled tcpdump; then
+ if [[ -z "${TCPDUMP_ARGS}" ]]; then
+ die $LINENO "The tcpdump service requires TCPDUMP_ARGS to be set"
+ fi
+ touch ${TCPDUMP_OUTPUT}
+ run_process tcpdump "/usr/sbin/tcpdump -w $TCPDUMP_OUTPUT $TCPDUMP_ARGS" root root
+ fi
+}
+
+# stop_tcpdump() stop tcpdump process
+function stop_tcpdump {
+ stop_process tcpdump
+}
+
+# Restore xtrace
+$_XTRACE_TCPDUMP
diff --git a/lib/tempest b/lib/tempest
index fba8826..a8f107a 100644
--- a/lib/tempest
+++ b/lib/tempest
@@ -102,6 +102,14 @@
remove_disabled_services "$extensions_list" "$disabled_exts"
}
+# image_size_in_gib - converts an image size from bytes to GiB, rounded up
+# Takes an image ID parameter as input
+function image_size_in_gib {
+ local size
+ size=$(openstack image show $1 -c size -f value)
+ echo $size | python -c "import math; print int(math.ceil(float(int(raw_input()) / 1024.0 ** 3)))"
+}
+
# configure_tempest() - Set config files, create data dirs, etc
function configure_tempest {
if [[ "$INSTALL_TEMPEST" == "True" ]]; then
@@ -125,6 +133,7 @@
local public_network_id
local public_router_id
local ssh_connect_method="floating"
+ local disk
# Save IFS
ifs=$IFS
@@ -190,11 +199,15 @@
available_flavors=$(nova flavor-list)
if [[ -z "$DEFAULT_INSTANCE_TYPE" ]]; then
if [[ ! ( $available_flavors =~ 'm1.nano' ) ]]; then
- openstack flavor create --id 42 --ram 64 --disk 0 --vcpus 1 m1.nano
+ # Determine the flavor disk size based on the image size.
+ disk=$(image_size_in_gib $image_uuid)
+ openstack flavor create --id 42 --ram 64 --disk $disk --vcpus 1 m1.nano
fi
flavor_ref=42
if [[ ! ( $available_flavors =~ 'm1.micro' ) ]]; then
- openstack flavor create --id 84 --ram 128 --disk 0 --vcpus 1 m1.micro
+ # Determine the alt flavor disk size based on the alt image size.
+ disk=$(image_size_in_gib $image_uuid_alt)
+ openstack flavor create --id 84 --ram 128 --disk $disk --vcpus 1 m1.micro
fi
flavor_ref_alt=84
else
@@ -242,6 +255,9 @@
# and the public_network_id should not be set.
if [[ "$NEUTRON_CREATE_INITIAL_NETWORKS" == "True" ]] && is_networking_extension_supported 'external-net'; then
public_network_id=$(openstack network show -f value -c id $PUBLIC_NETWORK_NAME)
+ # make sure shared network presence does not confuses the tempest tests
+ openstack network create --share shared
+ openstack subnet create --description shared-subnet --subnet-range ${TEMPEST_SHARED_POOL:-192.168.233.0/24} --network shared shared-subnet
fi
iniset $TEMPEST_CONFIG DEFAULT use_syslog $SYSLOG
@@ -263,8 +279,6 @@
iniset $TEMPEST_CONFIG identity user_lockout_failure_attempts $KEYSTONE_LOCKOUT_FAILURE_ATTEMPTS
iniset $TEMPEST_CONFIG identity user_lockout_duration $KEYSTONE_LOCKOUT_DURATION
iniset $TEMPEST_CONFIG identity user_unique_last_password_count $KEYSTONE_UNIQUE_LAST_PASSWORD_COUNT
- # Use domain scoped tokens for admin v3 tests, v3 dynamic credentials of v3 account generation
- iniset $TEMPEST_CONFIG identity admin_domain_scope True
if [[ "$TEMPEST_HAS_ADMIN" == "True" ]]; then
iniset $TEMPEST_CONFIG auth admin_username $admin_username
iniset $TEMPEST_CONFIG auth admin_password "$password"
@@ -660,7 +674,9 @@
function install_tempest_plugins {
pushd $TEMPEST_DIR
if [[ $TEMPEST_PLUGINS != 0 ]] ; then
- tox -evenv-tempest -- pip install -c $REQUIREMENTS_DIR/upper-constraints.txt $TEMPEST_PLUGINS
+ # The requirements might be on a different branch, while tempest & tempest plugins needs master requirements.
+ (cd $REQUIREMENTS_DIR && git show origin/master:upper-constraints.txt) > u-c-m.txt
+ tox -evenv-tempest -- pip install -c u-c-m.txt $TEMPEST_PLUGINS
echo "Checking installed Tempest plugins:"
tox -evenv-tempest -- tempest list-plugins
fi
diff --git a/roles/capture-system-logs/tasks/main.yaml b/roles/capture-system-logs/tasks/main.yaml
index de4f8ed..905806d 100644
--- a/roles/capture-system-logs/tasks/main.yaml
+++ b/roles/capture-system-logs/tasks/main.yaml
@@ -19,6 +19,17 @@
rpm -qa | sort > {{ stage_dir }}/rpm-qa.txt
fi
+ # NOTE(kchamart) The 'audit.log' can be useful in cases when QEMU
+ # failed to start due to denials from SELinux — useful for CentOS
+ # and Fedora machines. For Ubuntu (which runs AppArmor), DevStack
+ # already captures the contents of /var/log/kern.log (via
+ # `journalctl -t kernel` redirected into syslog.txt.gz), which
+ # contains AppArmor-related messages.
+ if [ -f /var/log/audit/audit.log ] ; then
+ sudo cp /var/log/audit/audit.log {{stage_dir }}/audit.log &&
+ chmod +r {{ stage_dir }}/audit.log;
+ fi
+
# gzip and save any coredumps in /var/core
if [ -d /var/core ]; then
sudo gzip -r /var/core
diff --git a/roles/export-devstack-journal/README.rst b/roles/export-devstack-journal/README.rst
index a34e070..9e3c919 100644
--- a/roles/export-devstack-journal/README.rst
+++ b/roles/export-devstack-journal/README.rst
@@ -1,11 +1,15 @@
Export journal files from devstack services
-Export the systemd journal for every devstack service in native
-journal format as well as text. Also, export a syslog-style file with
-kernal and sudo messages.
+This performs a number of logging collection services
-Writes the output to the ``logs/`` subdirectory of
-``stage_dir``.
+* Export the systemd journal in native format
+* For every devstack service, export logs to text in a file named
+ ``screen-*`` to maintain legacy compatability when devstack services
+ used to run in a screen session and were logged separately.
+* Export a syslog-style file with kernel and sudo messages for legacy
+ compatability.
+
+Writes the output to the ``logs/`` subdirectory of ``stage_dir``.
**Role Variables**
diff --git a/roles/export-devstack-journal/tasks/main.yaml b/roles/export-devstack-journal/tasks/main.yaml
index 6e760c1..cbec444 100644
--- a/roles/export-devstack-journal/tasks/main.yaml
+++ b/roles/export-devstack-journal/tasks/main.yaml
@@ -6,32 +6,49 @@
state: directory
owner: "{{ ansible_user }}"
-# TODO: convert this to ansible
-- name: Export journal files
+- name: Export legacy stack screen log files
become: true
shell:
cmd: |
u=""
name=""
- for u in `systemctl list-unit-files | grep devstack | awk '{print $1}'`; do
+ for u in $(systemctl list-unit-files | grep devstack | awk '{print $1}'); do
name=$(echo $u | sed 's/devstack@/screen-/' | sed 's/\.service//')
journalctl -o short-precise --unit $u | gzip - > {{ stage_dir }}/logs/$name.txt.gz
done
- # Export the journal in export format to make it downloadable
- # for later searching. It can then be rewritten to a journal native
- # format locally using systemd-journal-remote. This makes a class of
- # debugging much easier. We don't do the native conversion here as
- # some distros do not package that tooling.
- journalctl -u 'devstack@*' -o export | \
- xz --threads=0 - > {{ stage_dir }}/logs/devstack.journal.xz
-
- # The journal contains everything running under systemd, we'll
- # build an old school version of the syslog with just the
- # kernel and sudo messages.
+- name: Export legacy syslog.txt
+ become: true
+ shell:
+ # The journal contains everything running under systemd, we'll
+ # build an old school version of the syslog with just the
+ # kernel and sudo messages.
+ cmd: |
journalctl \
-t kernel \
-t sudo \
--no-pager \
--since="$(cat {{ devstack_base_dir }}/log-start-timestamp.txt)" \
| gzip - > {{ stage_dir }}/logs/syslog.txt.gz
+
+# TODO: convert this to ansible
+# - make a list of the above units
+# - iterate the list here
+- name: Export journal
+ become: true
+ shell:
+ # Export the journal in export format to make it downloadable
+ # for later searching. It can then be rewritten to a journal native
+ # format locally using systemd-journal-remote. This makes a class of
+ # debugging much easier. We don't do the native conversion here as
+ # some distros do not package that tooling.
+ cmd: |
+ journalctl -o export \
+ --since="$(cat {{ devstack_base_dir }}/log-start-timestamp.txt)" \
+ | xz --threads=0 - > {{ stage_dir }}/logs/devstack.journal.xz
+
+- name: Save journal README
+ become: true
+ template:
+ src: devstack.journal.README.txt.j2
+ dest: '{{ stage_dir }}/logs/devstack.journal.README.txt'
diff --git a/roles/export-devstack-journal/templates/devstack.journal.README.txt.j2 b/roles/export-devstack-journal/templates/devstack.journal.README.txt.j2
new file mode 100644
index 0000000..598eb7f
--- /dev/null
+++ b/roles/export-devstack-journal/templates/devstack.journal.README.txt.j2
@@ -0,0 +1,33 @@
+Devstack systemd journal
+========================
+
+The devstack.journal file is a copy of the systemd journal during the
+devstack run.
+
+To use it, you will need to convert it so journalctl can read it
+locally. After downloading the file:
+
+ $ /lib/systemd/systemd-journal-remote <(xzcat ./devstack.journal.xz) -o output.journal
+
+Note this binary is not in the regular path. On Debian/Ubuntu
+platforms, you will need to have the "sytemd-journal-remote" package
+installed.
+
+It should result in something like:
+
+ Finishing after writing <large number> entries
+
+You can then use journalctl to examine this file. For example, to see
+all devstack services try:
+
+ $ journalctl --file ./output.journal -u 'devstack@*'
+
+To see just cinder API server logs restrict the match with
+
+ $ journalctl --file ./output.journal -u 'devstack@c-api'
+
+There may be many types of logs available in the journal, a command like
+
+ $ journalctl --file ./output.journal --output=json-pretty | grep "_SYSTEMD_UNIT" | sort -u
+
+can help you find interesting things to filter on.
\ No newline at end of file
diff --git a/roles/fetch-devstack-log-dir/tasks/main.yaml b/roles/fetch-devstack-log-dir/tasks/main.yaml
index 5a198b2..276c4e0 100644
--- a/roles/fetch-devstack-log-dir/tasks/main.yaml
+++ b/roles/fetch-devstack-log-dir/tasks/main.yaml
@@ -1,5 +1,10 @@
+# as the user in the guest may not exist on the executor
+# we do not preserve the group or owner of the copied logs.
+
- name: Collect devstack logs
synchronize:
dest: "{{ zuul.executor.log_root }}/{{ inventory_hostname }}"
mode: pull
src: "{{ devstack_base_dir }}/logs"
+ group: no
+ owner: no
diff --git a/roles/setup-devstack-source-dirs/tasks/main.yaml b/roles/setup-devstack-source-dirs/tasks/main.yaml
index c196c37..dfa934f 100644
--- a/roles/setup-devstack-source-dirs/tasks/main.yaml
+++ b/roles/setup-devstack-source-dirs/tasks/main.yaml
@@ -1,4 +1,4 @@
-- name: Find all source repos used by this job
+- name: Find all OpenStack source repos used by this job
find:
paths:
- src/git.openstack.org/openstack
@@ -12,6 +12,30 @@
with_items: '{{ found_repos.files }}'
become: yes
+# Github projects are github.com/username/repo (username might be a
+# top-level project too), so we have to do a two-step swizzle to just
+# get the full repo path (ansible's find module doesn't help with this
+# :/)
+- name: Find top level github projects
+ find:
+ paths:
+ - src/github.com
+ file_type: directory
+ register: found_github_projects
+
+- name: Find actual github repos
+ find:
+ paths: '{{ found_github_projects.files | map(attribute="path") | list }}'
+ file_type: directory
+ register: found_github_repos
+ when: found_github_projects.files
+
+- name: Copy github repos into devstack working directory
+ command: rsync -a {{ item.path }} {{ devstack_base_dir }}
+ with_items: '{{ found_github_repos.files }}'
+ become: yes
+ when: found_github_projects.files
+
- name: Setup refspec for repos into devstack working directory
shell:
# Copied almost "as-is" from devstack-gate setup-workspace function
diff --git a/roles/write-devstack-local-conf/README.rst b/roles/write-devstack-local-conf/README.rst
index e9739cd..d0a51e7 100644
--- a/roles/write-devstack-local-conf/README.rst
+++ b/roles/write-devstack-local-conf/README.rst
@@ -88,3 +88,12 @@
If a plugin declares a dependency on another plugin (via
``plugin_requires`` in the plugin's settings file), this role will
automatically emit ``enable_plugin`` lines in the correct order.
+
+.. zuul:rolevar:: tempest_plugins
+ :type: list
+
+ A list of tempest plugins which are installed alongside tempest.
+
+ The list of values will be combined with the base devstack directory
+ and used to populate the ``TEMPEST_PLUGINS`` variable. If the variable
+ already exists, its value is *not* changed.
diff --git a/roles/write-devstack-local-conf/library/devstack_local_conf.py b/roles/write-devstack-local-conf/library/devstack_local_conf.py
index bba7e31..2f97d0e 100644
--- a/roles/write-devstack-local-conf/library/devstack_local_conf.py
+++ b/roles/write-devstack-local-conf/library/devstack_local_conf.py
@@ -155,8 +155,8 @@
continue
self.loadDevstackPluginInfo(settings)
- define_re = re.compile(r'^define_plugin\s+(\w+).*')
- require_re = re.compile(r'^plugin_requires\s+(\w+)\s+(\w+).*')
+ define_re = re.compile(r'^define_plugin\s+(\S+).*')
+ require_re = re.compile(r'^plugin_requires\s+(\S+)\s+(\S+).*')
def loadDevstackPluginInfo(self, fn):
name = None
reqs = set()
@@ -207,18 +207,23 @@
class LocalConf(object):
def __init__(self, localrc, localconf, base_services, services, plugins,
- base_dir, projects, project):
+ base_dir, projects, project, tempest_plugins):
self.localrc = []
+ self.warnings = []
self.meta_sections = {}
self.plugin_deps = {}
self.base_dir = base_dir
self.projects = projects
self.project = project
- if plugins:
- self.handle_plugins(plugins)
+ self.tempest_plugins = tempest_plugins
if services or base_services:
self.handle_services(base_services, services or {})
self.handle_localrc(localrc)
+ # Plugins must be the last items in localrc, otherwise
+ # the configuration lines which follows them in the file are
+ # not applied to the plugins (for example, the value of DEST.)
+ if plugins:
+ self.handle_plugins(plugins)
if localconf:
self.handle_localconf(localconf)
@@ -243,12 +248,19 @@
def handle_localrc(self, localrc):
lfg = False
+ tp = False
if localrc:
vg = VarGraph(localrc)
for k, v in vg.getVars():
- self.localrc.append('{}={}'.format(k, v))
+ # Avoid double quoting
+ if len(v) and v[0]=='"':
+ self.localrc.append('{}={}'.format(k, v))
+ else:
+ self.localrc.append('{}="{}"'.format(k, v))
if k == 'LIBS_FROM_GIT':
lfg = True
+ elif k == 'TEMPEST_PLUGINS':
+ tp = True
if not lfg and (self.projects or self.project):
required_projects = []
@@ -263,6 +275,19 @@
self.localrc.append('LIBS_FROM_GIT={}'.format(
','.join(required_projects)))
+ if self.tempest_plugins:
+ if not tp:
+ tp_dirs = []
+ for tempest_plugin in self.tempest_plugins:
+ tp_dirs.append(os.path.join(self.base_dir, tempest_plugin))
+ self.localrc.append('TEMPEST_PLUGINS="{}"'.format(
+ ' '.join(tp_dirs)))
+ else:
+ self.warnings.append('TEMPEST_PLUGINS already defined ({}),'
+ 'requested value {} ignored'.format(
+ tp, self.tempest_plugins))
+
+
def handle_localconf(self, localconf):
for phase, phase_data in localconf.items():
for fn, fn_data in phase_data.items():
@@ -297,6 +322,7 @@
path=dict(type='str'),
projects=dict(type='dict'),
project=dict(type='dict'),
+ tempest_plugins=dict(type='list'),
)
)
@@ -308,10 +334,11 @@
p.get('plugins'),
p.get('base_dir'),
p.get('projects'),
- p.get('project'))
+ p.get('project'),
+ p.get('tempest_plugins'))
lc.write(p['path'])
- module.exit_json()
+ module.exit_json(warnings=lc.warnings)
try:
diff --git a/roles/write-devstack-local-conf/library/test.py b/roles/write-devstack-local-conf/library/test.py
index 791552d..7c526b3 100644
--- a/roles/write-devstack-local-conf/library/test.py
+++ b/roles/write-devstack-local-conf/library/test.py
@@ -23,6 +23,20 @@
from collections import OrderedDict
class TestDevstackLocalConf(unittest.TestCase):
+
+ @staticmethod
+ def _init_localconf(p):
+ lc = LocalConf(p.get('localrc'),
+ p.get('local_conf'),
+ p.get('base_services'),
+ p.get('services'),
+ p.get('plugins'),
+ p.get('base_dir'),
+ p.get('projects'),
+ p.get('project'),
+ p.get('tempest_plugins'))
+ return lc
+
def setUp(self):
self.tmpdir = tempfile.mkdtemp()
@@ -40,9 +54,9 @@
# We use ordereddict here to make sure the plugins are in the
# *wrong* order for testing.
plugins = OrderedDict([
- ('bar', 'git://git.openstack.org/openstack/bar-plugin'),
- ('foo', 'git://git.openstack.org/openstack/foo-plugin'),
- ('baz', 'git://git.openstack.org/openstack/baz-plugin'),
+ ('bar', 'https://git.openstack.org/openstack/bar-plugin'),
+ ('foo', 'https://git.openstack.org/openstack/foo-plugin'),
+ ('baz', 'https://git.openstack.org/openstack/baz-plugin'),
])
p = dict(localrc=localrc,
local_conf=local_conf,
@@ -51,14 +65,7 @@
plugins=plugins,
base_dir='./test',
path=os.path.join(self.tmpdir, 'test.local.conf'))
- lc = LocalConf(p.get('localrc'),
- p.get('local_conf'),
- p.get('base_services'),
- p.get('services'),
- p.get('plugins'),
- p.get('base_dir'),
- p.get('projects'),
- p.get('project'))
+ lc = self._init_localconf(p)
lc.write(p['path'])
plugins = []
@@ -78,12 +85,12 @@
with open(os.path.join(
self.tmpdir,
'foo-plugin', 'devstack', 'settings'), 'w') as f:
- f.write('define_plugin foo\n')
+ f.write('define_plugin foo-plugin\n')
with open(os.path.join(
self.tmpdir,
'bar-plugin', 'devstack', 'settings'), 'w') as f:
- f.write('define_plugin bar\n')
- f.write('plugin_requires bar foo\n')
+ f.write('define_plugin bar-plugin\n')
+ f.write('plugin_requires bar-plugin foo-plugin\n')
localrc = {'test_localrc': '1'}
local_conf = {'install':
@@ -94,8 +101,8 @@
# We use ordereddict here to make sure the plugins are in the
# *wrong* order for testing.
plugins = OrderedDict([
- ('bar', 'git://git.openstack.org/openstack/bar-plugin'),
- ('foo', 'git://git.openstack.org/openstack/foo-plugin'),
+ ('bar-plugin', 'https://git.openstack.org/openstack/bar-plugin'),
+ ('foo-plugin', 'https://git.openstack.org/openstack/foo-plugin'),
])
p = dict(localrc=localrc,
local_conf=local_conf,
@@ -104,6 +111,15 @@
plugins=plugins,
base_dir=self.tmpdir,
path=os.path.join(self.tmpdir, 'test.local.conf'))
+ lc = self._init_localconf(p)
+ lc.write(p['path'])
+
+ plugins = []
+ with open(p['path']) as f:
+ for line in f:
+ if line.startswith('enable_plugin'):
+ plugins.append(line.split()[1])
+ self.assertEqual(['foo-plugin', 'bar-plugin'], plugins)
def test_libs_from_git(self):
"Test that LIBS_FROM_GIT is auto-generated"
@@ -129,14 +145,7 @@
path=os.path.join(self.tmpdir, 'test.local.conf'),
projects=projects,
project=project)
- lc = LocalConf(p.get('localrc'),
- p.get('local_conf'),
- p.get('base_services'),
- p.get('services'),
- p.get('plugins'),
- p.get('base_dir'),
- p.get('projects'),
- p.get('project'))
+ lc = self._init_localconf(p)
lc.write(p['path'])
lfg = None
@@ -168,14 +177,7 @@
base_dir='./test',
path=os.path.join(self.tmpdir, 'test.local.conf'),
projects=projects)
- lc = LocalConf(p.get('localrc'),
- p.get('local_conf'),
- p.get('base_services'),
- p.get('services'),
- p.get('plugins'),
- p.get('base_dir'),
- p.get('projects'),
- p.get('project'))
+ lc = self._init_localconf(p)
lc.write(p['path'])
lfg = None
@@ -183,7 +185,25 @@
for line in f:
if line.startswith('LIBS_FROM_GIT'):
lfg = line.strip().split('=')[1]
- self.assertEqual('oslo.db', lfg)
+ self.assertEqual('"oslo.db"', lfg)
+
+ def test_avoid_double_quote(self):
+ "Test that there a no duplicated quotes"
+ localrc = {'TESTVAR': '"quoted value"'}
+ p = dict(localrc=localrc,
+ base_services=[],
+ base_dir='./test',
+ path=os.path.join(self.tmpdir, 'test.local.conf'),
+ projects={})
+ lc = self._init_localconf(p)
+ lc.write(p['path'])
+
+ testvar = None
+ with open(p['path']) as f:
+ for line in f:
+ if line.startswith('TESTVAR'):
+ testvar = line.strip().split('=')[1]
+ self.assertEqual('"quoted value"', testvar)
def test_plugin_circular_deps(self):
"Test that plugins with circular dependencies fail"
@@ -211,8 +231,8 @@
# We use ordereddict here to make sure the plugins are in the
# *wrong* order for testing.
plugins = OrderedDict([
- ('bar', 'git://git.openstack.org/openstack/bar-plugin'),
- ('foo', 'git://git.openstack.org/openstack/foo-plugin'),
+ ('bar', 'https://git.openstack.org/openstack/bar-plugin'),
+ ('foo', 'https://git.openstack.org/openstack/foo-plugin'),
])
p = dict(localrc=localrc,
local_conf=local_conf,
@@ -222,14 +242,50 @@
base_dir=self.tmpdir,
path=os.path.join(self.tmpdir, 'test.local.conf'))
with self.assertRaises(Exception):
- lc = LocalConf(p.get('localrc'),
- p.get('local_conf'),
- p.get('base_services'),
- p.get('services'),
- p.get('plugins'),
- p.get('base_dir'))
+ lc = self._init_localconf(p)
lc.write(p['path'])
+ def _find_tempest_plugins_value(self, file_path):
+ tp = None
+ with open(file_path) as f:
+ for line in f:
+ if line.startswith('TEMPEST_PLUGINS'):
+ found = line.strip().split('=')[1]
+ self.assertIsNone(tp,
+ "TEMPEST_PLUGIN ({}) found again ({})".format(
+ tp, found))
+ tp = found
+ return tp
+
+ def test_tempest_plugins(self):
+ "Test that TEMPEST_PLUGINS is correctly populated."
+ p = dict(base_services=[],
+ base_dir='./test',
+ path=os.path.join(self.tmpdir, 'test.local.conf'),
+ tempest_plugins=['heat-tempest-plugin', 'sahara-tests'])
+ lc = self._init_localconf(p)
+ lc.write(p['path'])
+
+ tp = self._find_tempest_plugins_value(p['path'])
+ self.assertEqual('"./test/heat-tempest-plugin ./test/sahara-tests"', tp)
+ self.assertEqual(len(lc.warnings), 0)
+
+ def test_tempest_plugins_not_overridden(self):
+ """Test that the existing value of TEMPEST_PLUGINS is not overridden
+ by the user-provided value, but a warning is emitted."""
+ localrc = {'TEMPEST_PLUGINS': 'someplugin'}
+ p = dict(localrc=localrc,
+ base_services=[],
+ base_dir='./test',
+ path=os.path.join(self.tmpdir, 'test.local.conf'),
+ tempest_plugins=['heat-tempest-plugin', 'sahara-tests'])
+ lc = self._init_localconf(p)
+ lc.write(p['path'])
+
+ tp = self._find_tempest_plugins_value(p['path'])
+ self.assertEqual('"someplugin"', tp)
+ self.assertEqual(len(lc.warnings), 1)
+
if __name__ == '__main__':
unittest.main()
diff --git a/roles/write-devstack-local-conf/tasks/main.yaml b/roles/write-devstack-local-conf/tasks/main.yaml
index 9a6b083..bfd0860 100644
--- a/roles/write-devstack-local-conf/tasks/main.yaml
+++ b/roles/write-devstack-local-conf/tasks/main.yaml
@@ -10,4 +10,5 @@
local_conf: "{{ devstack_local_conf|default(omit) }}"
base_dir: "{{ devstack_base_dir|default(omit) }}"
projects: "{{ zuul.projects }}"
- project: "{{ zuul.project }}"
\ No newline at end of file
+ project: "{{ zuul.project }}"
+ tempest_plugins: "{{ tempest_plugins|default(omit) }}"
diff --git a/stack.sh b/stack.sh
index 144c233..0d7e623 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-15.0|opensuse-tumbleweed|rhel7) ]]; then
+if [[ ! ${DISTRO} =~ (xenial|artful|bionic|stretch|jessie|f28|f29|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"
@@ -614,6 +614,7 @@
source $TOP_DIR/lib/neutron
source $TOP_DIR/lib/ldap
source $TOP_DIR/lib/dstat
+source $TOP_DIR/lib/tcpdump
source $TOP_DIR/lib/etcd3
# Extras Source
@@ -801,6 +802,11 @@
# Install required infra support libraries
install_infra
+# Install bindep
+$VIRTUALENV_CMD $DEST/bindep-venv
+# TODO(ianw) : optionally install from zuul checkout?
+$DEST/bindep-venv/bin/pip install bindep
+
# Extras Pre-install
# ------------------
# Phase: pre-install
@@ -827,6 +833,18 @@
install_etcd3
fi
+# Setup TLS certs
+# ---------------
+
+# Do this early, before any webservers are set up to ensure
+# we don't run into problems with missing certs when apache
+# is restarted.
+if is_service_enabled tls-proxy; then
+ configure_CA
+ init_CA
+ init_cert
+fi
+
# Check Out and Install Source
# ----------------------------
@@ -851,13 +869,6 @@
install_neutronclient
fi
-# Setup TLS certs
-if is_service_enabled tls-proxy; then
- configure_CA
- init_CA
- init_cert
-fi
-
# Install middleware
install_keystonemiddleware
@@ -1048,6 +1059,12 @@
# A better kind of sysstat, with the top process per time slice
start_dstat
+# Run a background tcpdump for debugging
+# Note: must set TCPDUMP_ARGS with the enabled service
+if is_service_enabled tcpdump; then
+ start_tcpdump
+fi
+
# Etcd
# -----
diff --git a/stackrc b/stackrc
index 8463313..2924d39 100644
--- a/stackrc
+++ b/stackrc
@@ -129,15 +129,9 @@
# Control whether Python 3 should be used at all.
export USE_PYTHON3=$(trueorfalse False USE_PYTHON3)
-# Control whether Python 3 is enabled for specific services by the
-# base name of the directory from which they are installed. See
-# enable_python3_package to edit this variable and use_python3_for to
-# test membership.
-export ENABLED_PYTHON3_PACKAGES="nova,glance,cinder,uwsgi,python-openstackclient,openstacksdk"
-
# Explicitly list services not to run under Python 3. See
# disable_python3_package to edit this variable.
-export DISABLED_PYTHON3_PACKAGES=""
+export DISABLED_PYTHON3_PACKAGES="swift"
# When Python 3 is supported by an application, adding the specific
# version of Python 3 to this variable will install the app using that
@@ -149,6 +143,13 @@
_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
+ export VIRTUALENV_CMD="python3 -m venv"
+else
+ export VIRTUALENV_CMD="virtualenv "
+fi
+
# allow local overrides of env variables, including repo config
if [[ -f $RC_DIR/localrc ]]; then
# Old-style user-supplied config
@@ -236,8 +237,7 @@
# ------------
# Base GIT Repo URL
-# Another option is https://git.openstack.org
-GIT_BASE=${GIT_BASE:-git://git.openstack.org}
+GIT_BASE=${GIT_BASE:-https://git.openstack.org}
# The location of REQUIREMENTS once cloned
REQUIREMENTS_DIR=$DEST/requirements
@@ -258,7 +258,7 @@
# Setting the variable to 'ALL' will activate the download for all
# libraries.
-DEVSTACK_SERIES="stein"
+DEVSTACK_SERIES="train"
##############
#
@@ -607,7 +607,7 @@
# a websockets/html5 or flash powered VNC console for vm instances
NOVNC_REPO=${NOVNC_REPO:-https://github.com/novnc/noVNC.git}
-NOVNC_BRANCH=${NOVNC_BRANCH:-stable/v0.6}
+NOVNC_BRANCH=${NOVNC_BRANCH:-v1.0.0}
# a websockets/html5 or flash powered SPICE console for vm instances
SPICE_REPO=${SPICE_REPO:-http://anongit.freedesktop.org/git/spice/spice-html5.git}
@@ -685,7 +685,7 @@
#IMAGE_URLS="http://smoser.brickies.net/ubuntu/ttylinux-uec/ttylinux-uec-amd64-11.2_2.6.35-15_1.tar.gz" # old ttylinux-uec image
#IMAGE_URLS="http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-disk.img" # cirros full disk image
-CIRROS_VERSION=${CIRROS_VERSION:-"0.3.6"}
+CIRROS_VERSION=${CIRROS_VERSION:-"0.4.0"}
CIRROS_ARCH=${CIRROS_ARCH:-"x86_64"}
# Set default image based on ``VIRT_DRIVER`` and ``LIBVIRT_TYPE``, either of
@@ -736,10 +736,10 @@
EXTRA_CACHE_URLS=""
# etcd3 defaults
-ETCD_VERSION=${ETCD_VERSION:-v3.2.17}
-ETCD_SHA256_AMD64=${ETCD_SHA256_AMD64:-"0a75e794502e2e76417b19da2807a9915fa58dcbf0985e397741d570f4f305cd"}
-ETCD_SHA256_ARM64=${ETCD_SHA256_ARM64:-"0ab4621c44c79d17d94e43bd184d0f23b763a3669056ce4ae2d0b2942410a98f"}
-ETCD_SHA256_PPC64=${ETCD_SHA256_PPC64:-"69e1279c4a2a52256b78d2a8dd23346ac46b836e678b971a459f2afaef3c275e"}
+ETCD_VERSION=${ETCD_VERSION:-v3.3.12}
+ETCD_SHA256_AMD64=${ETCD_SHA256_AMD64:-"dc5d82df095dae0a2970e4d870b6929590689dd707ae3d33e7b86da0f7f211b6"}
+ETCD_SHA256_ARM64=${ETCD_SHA256_ARM64:-"170b848ac1a071fe7d495d404a868a2c0090750b2944f8a260ef1c6125b2b4f4"}
+ETCD_SHA256_PPC64=${ETCD_SHA256_PPC64:-"77f807b1b51abbf51e020bb05bdb8ce088cb58260fcd22749ea32eee710463d3"}
# etcd v3.2.x doesn't have anything for s390x
ETCD_SHA256_S390X=${ETCD_SHA256_S390X:-""}
# Make sure etcd3 downloads the correct architecture
diff --git a/tests/test_functions.sh b/tests/test_functions.sh
index adf20cd..08143d2 100755
--- a/tests/test_functions.sh
+++ b/tests/test_functions.sh
@@ -272,7 +272,7 @@
export_proxy_variables
expected=$(echo -e "http_proxy=$http_proxy\nhttps_proxy=$https_proxy\nno_proxy=$no_proxy")
- results=$(env | egrep '(http(s)?|no)_proxy=')
+ results=$(env | egrep '(http(s)?|no)_proxy=' | sort)
if [[ $expected = $results ]]; then
passed "OK: Proxy variables are exported when proxy variables are set"
else
diff --git a/tests/test_ini_config.sh b/tests/test_ini_config.sh
index f7dc89a..6ed1647 100755
--- a/tests/test_ini_config.sh
+++ b/tests/test_ini_config.sh
@@ -125,14 +125,14 @@
assert_equal "$VAL" "33,44" "inset at EOF"
# test empty option
-if ini_has_option ${TEST_INI} ddd empty; then
+if ini_has_option ${SUDO_ARG} ${TEST_INI} ddd empty; then
passed "ini_has_option: ddd.empty present"
else
failed "ini_has_option failed: ddd.empty not found"
fi
# test non-empty option
-if ini_has_option ${TEST_INI} bbb handlers; then
+if ini_has_option ${SUDO_ARG} ${TEST_INI} bbb handlers; then
passed "ini_has_option: bbb.handlers present"
else
failed "ini_has_option failed: bbb.handlers not found"
diff --git a/tests/test_python.sh b/tests/test_python.sh
index 8652798..1f5453c 100755
--- a/tests/test_python.sh
+++ b/tests/test_python.sh
@@ -12,14 +12,9 @@
echo "Testing Python 3 functions"
# Initialize variables manipulated by functions under test.
-export ENABLED_PYTHON3_PACKAGES=""
export DISABLED_PYTHON3_PACKAGES=""
-assert_false "should not be enabled yet" python3_enabled_for testpackage1
-
-enable_python3_package testpackage1
-assert_equal "$ENABLED_PYTHON3_PACKAGES" "testpackage1" "unexpected result"
-assert_true "should be enabled" python3_enabled_for testpackage1
+assert_true "should be enabled by default" python3_enabled_for testpackage1
assert_false "should not be disabled yet" python3_disabled_for testpackage2
diff --git a/tools/dstat.sh b/tools/dstat.sh
index 01c6d9b..e6cbb0f 100755
--- a/tools/dstat.sh
+++ b/tools/dstat.sh
@@ -12,8 +12,17 @@
# Retrieve log directory as argument from calling script.
LOGDIR=$1
+DSTAT_TOP_OPTS="--top-cpu-adv --top-io-adv --top-mem"
+if dstat --version | grep -q 'pcp-dstat' ; then
+ # dstat is unmaintained, and moving to a plugin of performance
+ # co-pilot. Fedora 29 for example has rolled this out. It's
+ # mostly compatible, except for a few options which are not
+ # implemented (yet?)
+ DSTAT_TOP_OPTS=""
+fi
+
# Command line arguments for primary DStat process.
-DSTAT_OPTS="-tcmndrylpg --top-cpu-adv --top-io-adv --top-mem --swap --tcp"
+DSTAT_OPTS="-tcmndrylpg ${DSTAT_TOP_OPTS} --swap --tcp"
# Command-line arguments for secondary background DStat process.
DSTAT_CSV_OPTS="-tcmndrylpg --tcp --output $LOGDIR/dstat-csv.log"
diff --git a/tools/fixup_stuff.sh b/tools/fixup_stuff.sh
index a939e30..1ff7bfa 100755
--- a/tools/fixup_stuff.sh
+++ b/tools/fixup_stuff.sh
@@ -202,7 +202,19 @@
# install requests with the bundled urllib3 to avoid conflicts
pip_install --upgrade --force-reinstall requests
fi
+
fi
+
+ # Since pip10, pip will refuse to uninstall files from packages
+ # that were created with distutils (rather than more modern
+ # setuptools). This is because it technically doesn't have a
+ # manifest of what to remove. However, in most cases, simply
+ # overwriting works. So this hacks around those packages that
+ # have been dragged in by some other system dependency
+ sudo rm -rf /usr/lib/python2.7/site-packages/enum34*.egg-info
+ sudo rm -rf /usr/lib/python2.7/site-packages/ipaddress*.egg-info
+ sudo rm -rf /usr/lib/python2.7/site-packages/ply-*.egg-info
+ sudo rm -rf /usr/lib/python2.7/site-packages/typing-*.egg-info
}
function fixup_suse {
diff --git a/tools/generate-devstack-plugins-list.sh b/tools/generate-devstack-plugins-list.sh
index 95f1331..27c9c41 100755
--- a/tools/generate-devstack-plugins-list.sh
+++ b/tools/generate-devstack-plugins-list.sh
@@ -65,7 +65,7 @@
# ====================== ===
# Plugin Name URL
# ====================== ===
-# foobar `git://... <http://...>`__
+# foobar `https://... <https://...>`__
# ...
printf "\n\n"
@@ -74,7 +74,7 @@
title_underline ${name_col_len}
for plugin in ${sorted_plugins}; do
- giturl="git://git.openstack.org/openstack/${plugin}"
+ giturl="https://git.openstack.org/openstack/${plugin}"
gitlink="https://git.openstack.org/cgit/openstack/${plugin}"
printf "%-${name_col_len}s %s\n" "${plugin}" "\`${giturl} <${gitlink}>\`__"
done
diff --git a/tools/update_clouds_yaml.py b/tools/update_clouds_yaml.py
index eb7265f..9187c66 100755
--- a/tools/update_clouds_yaml.py
+++ b/tools/update_clouds_yaml.py
@@ -41,12 +41,19 @@
'auth_url': args.os_auth_url,
'username': args.os_username,
'password': args.os_password,
- 'project_name': args.os_project_name,
},
}
- if args.os_identity_api_version == '3':
+ if args.os_project_name and args.os_system_scope:
+ print(
+ "WARNING: os_project_name and os_system_scope were both"
+ " given. os_system_scope will take priority.")
+ if args.os_project_name and not args.os_system_scope:
+ self._cloud_data['auth']['project_name'] = args.os_project_name
+ if args.os_identity_api_version == '3' and not args.os_system_scope:
self._cloud_data['auth']['user_domain_id'] = 'default'
self._cloud_data['auth']['project_domain_id'] = 'default'
+ if args.os_system_scope:
+ self._cloud_data['auth']['system_scope'] = args.os_system_scope
if args.os_cacert:
self._cloud_data['cacert'] = args.os_cacert
@@ -83,12 +90,13 @@
parser.add_argument('--os-cloud', required=True)
parser.add_argument('--os-region-name', default='RegionOne')
parser.add_argument('--os-identity-api-version', default='3')
- parser.add_argument('--os-volume-api-version', default='2')
+ parser.add_argument('--os-volume-api-version', default='3')
parser.add_argument('--os-cacert')
parser.add_argument('--os-auth-url', required=True)
parser.add_argument('--os-username', required=True)
parser.add_argument('--os-password', required=True)
- parser.add_argument('--os-project-name', required=True)
+ parser.add_argument('--os-project-name')
+ parser.add_argument('--os-system-scope')
args = parser.parse_args()
diff --git a/tools/worlddump.py b/tools/worlddump.py
index 7506082..88af19d 100755
--- a/tools/worlddump.py
+++ b/tools/worlddump.py
@@ -163,7 +163,9 @@
def network_dump():
_header("Network Dump")
+ _dump_cmd("bridge link")
_dump_cmd("brctl show")
+ _dump_cmd("ip link show type bridge")
ip_cmds = ["neigh", "addr", "link", "route"]
for cmd in ip_cmds + ['netns']:
_dump_cmd("ip %s" % cmd)