Merge "Add config options for cinder nfs backend"
diff --git a/.zuul.yaml b/.zuul.yaml
index 8e20f6e..fa7f180 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -696,6 +696,9 @@
     description: |
       Simple multinode test to verify multinode functionality on devstack side.
       This is not meant to be used as a parent job.
+    vars:
+      devstack_localrc:
+        MYSQL_REDUCE_MEMORY: true
 
 # NOTE(ianw) Platform tests have traditionally been non-voting because
 # we often have to rush things through devstack to stabilise the gate,
diff --git a/lib/cinder b/lib/cinder
index bf2fe50..c50a205 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -95,6 +95,7 @@
 CINDER_VOLUME_CLEAR=${CINDER_VOLUME_CLEAR:-${CINDER_VOLUME_CLEAR_DEFAULT:-zero}}
 CINDER_VOLUME_CLEAR=$(echo ${CINDER_VOLUME_CLEAR} | tr '[:upper:]' '[:lower:]')
 
+VOLUME_TYPE_MULTIATTACH=${VOLUME_TYPE_MULTIATTACH:-multiattach}
 
 if [[ -n "$CINDER_ISCSI_HELPER" ]]; then
     if [[ -z "$CINDER_TARGET_HELPER" ]]; then
@@ -411,6 +412,9 @@
     if [[ "$CINDER_ENFORCE_SCOPE" == True || "$ENFORCE_SCOPE" == True ]] ; then
         iniset $CINDER_CONF oslo_policy enforce_scope true
         iniset $CINDER_CONF oslo_policy enforce_new_defaults true
+    else
+        iniset $CINDER_CONF oslo_policy enforce_scope false
+        iniset $CINDER_CONF oslo_policy enforce_new_defaults false
     fi
 }
 
@@ -646,6 +650,23 @@
     stop_process c-vol
 }
 
+function create_one_type {
+    type_name=$1
+    property_key=$2
+    property_value=$3
+    # NOTE (e0ne): openstack client doesn't work with cinder in noauth mode
+    if is_service_enabled keystone; then
+        openstack --os-region-name="$REGION_NAME" volume type create --property $property_key="$property_value" $type_name
+    else
+        # TODO (e0ne): use openstack client once it will support cinder in noauth mode:
+        # https://bugs.launchpad.net/python-cinderclient/+bug/1755279
+        local cinder_url
+        cinder_url=$CINDER_SERVICE_PROTOCOL://$SERVICE_HOST:$CINDER_SERVICE_PORT/v3
+        OS_USER_ID=$OS_USERNAME OS_PROJECT_ID=$OS_PROJECT_NAME cinder --os-auth-type noauth --os-endpoint=$cinder_url type-create $type_name
+        OS_USER_ID=$OS_USERNAME OS_PROJECT_ID=$OS_PROJECT_NAME cinder --os-auth-type noauth --os-endpoint=$cinder_url type-key $type_name set $property_key="$property_value"
+    fi
+}
+
 # create_volume_types() - Create Cinder's configured volume types
 function create_volume_types {
     # Create volume types
@@ -653,19 +674,13 @@
         local be be_name
         for be in ${CINDER_ENABLED_BACKENDS//,/ }; do
             be_name=${be##*:}
-            # NOTE (e0ne): openstack client doesn't work with cinder in noauth mode
-            if is_service_enabled keystone; then
-                openstack --os-region-name="$REGION_NAME" volume type create --property volume_backend_name="${be_name}" ${be_name}
-            else
-                # TODO (e0ne): use openstack client once it will support cinder in noauth mode:
-                # https://bugs.launchpad.net/python-cinderclient/+bug/1755279
-                local cinder_url
-                cinder_url=$CINDER_SERVICE_PROTOCOL://$SERVICE_HOST:$CINDER_SERVICE_PORT/v3
-                OS_USER_ID=$OS_USERNAME OS_PROJECT_ID=$OS_PROJECT_NAME cinder --os-auth-type noauth --os-endpoint=$cinder_url type-create ${be_name}
-                OS_USER_ID=$OS_USERNAME OS_PROJECT_ID=$OS_PROJECT_NAME cinder --os-auth-type noauth --os-endpoint=$cinder_url type-key ${be_name} set volume_backend_name=${be_name}
-            fi
+            create_one_type $be_name "volume_backend_name" $be_name
         done
 
+        if [[ $ENABLE_VOLUME_MULTIATTACH == "True" ]]; then
+            create_one_type $VOLUME_TYPE_MULTIATTACH $VOLUME_TYPE_MULTIATTACH "<is> True"
+        fi
+
         # Increase quota for the service project if glance is using cinder,
         # since it's likely to occasionally go above the default 10 in parallel
         # test execution.
diff --git a/lib/databases/mysql b/lib/databases/mysql
index fbad44e..e805b3e 100644
--- a/lib/databases/mysql
+++ b/lib/databases/mysql
@@ -176,6 +176,16 @@
                 count INT, PRIMARY KEY (db, op)) ENGINE MEMORY" stats
     fi
 
+    if [[ "$MYSQL_REDUCE_MEMORY" == "True" ]]; then
+        iniset -sudo $my_conf mysqld read_buffer_size 64K
+        iniset -sudo $my_conf mysqld innodb_buffer_pool_size 16M
+        iniset -sudo $my_conf mysqld thread_stack 192K
+        iniset -sudo $my_conf mysqld thread_cache_size 8
+        iniset -sudo $my_conf mysqld tmp_table_size 8M
+        iniset -sudo $my_conf mysqld sort_buffer_size 8M
+        iniset -sudo $my_conf mysqld max_allowed_packet 8M
+    fi
+
     restart_service $MYSQL_SERVICE_NAME
 }
 
diff --git a/lib/glance b/lib/glance
index ba98f41..041acaf 100644
--- a/lib/glance
+++ b/lib/glance
@@ -436,6 +436,10 @@
         iniset $GLANCE_API_CONF oslo_policy enforce_scope true
         iniset $GLANCE_API_CONF oslo_policy enforce_new_defaults true
         iniset $GLANCE_API_CONF DEFAULT enforce_secure_rbac true
+    else
+        iniset $GLANCE_API_CONF oslo_policy enforce_scope false
+        iniset $GLANCE_API_CONF oslo_policy enforce_new_defaults false
+        iniset $GLANCE_API_CONF DEFAULT enforce_secure_rbac false
     fi
 }
 
diff --git a/lib/keystone b/lib/keystone
index 80a136f..6cb4aac 100644
--- a/lib/keystone
+++ b/lib/keystone
@@ -265,10 +265,15 @@
         iniset $KEYSTONE_CONF security_compliance lockout_duration $KEYSTONE_LOCKOUT_DURATION
         iniset $KEYSTONE_CONF security_compliance unique_last_password_count $KEYSTONE_UNIQUE_LAST_PASSWORD_COUNT
     fi
+
+    iniset $KEYSTONE_CONF oslo_policy policy_file policy.yaml
+
     if [[ "$KEYSTONE_ENFORCE_SCOPE" == True || "$ENFORCE_SCOPE" == True ]] ; then
         iniset $KEYSTONE_CONF oslo_policy enforce_scope true
         iniset $KEYSTONE_CONF oslo_policy enforce_new_defaults true
-        iniset $KEYSTONE_CONF oslo_policy policy_file policy.yaml
+    else
+        iniset $KEYSTONE_CONF oslo_policy enforce_scope false
+        iniset $KEYSTONE_CONF oslo_policy enforce_new_defaults false
     fi
 }
 
diff --git a/lib/neutron b/lib/neutron
index c8ee8c5..368a1b9 100644
--- a/lib/neutron
+++ b/lib/neutron
@@ -294,6 +294,7 @@
 source $TOP_DIR/lib/neutron_plugins/services/placement
 source $TOP_DIR/lib/neutron_plugins/services/trunk
 source $TOP_DIR/lib/neutron_plugins/services/qos
+source $TOP_DIR/lib/neutron_plugins/services/segments
 
 # Use security group or not
 if has_neutron_plugin_security_group; then
@@ -416,6 +417,10 @@
             configure_l3_agent_extension_gateway_ip_qos
         fi
     fi
+    if is_service_enabled neutron-segments; then
+        configure_placement_neutron
+        configure_segments_extension
+    fi
 
     # Finally configure Neutron server and core plugin
     if is_service_enabled q-agt neutron-agent q-svc neutron-api; then
@@ -527,7 +532,6 @@
     if use_library_from_git "python-neutronclient"; then
         git_clone_by_name "python-neutronclient"
         setup_dev_lib "python-neutronclient"
-        sudo install -D -m 0644 -o $STACK_USER {${GITDIR["python-neutronclient"]}/tools/,/etc/bash_completion.d/}neutron.bash_completion
     fi
 }
 
@@ -689,7 +693,9 @@
     fi
 
     if [[ "$Q_USE_ROOTWRAP_DAEMON" == "True" ]]; then
-        sudo pkill -9 -f $NEUTRON_ROOTWRAP-daemon || :
+        # pkill takes care not to kill itself, but it may kill its parent
+        # sudo unless we use the "ps | grep [f]oo" trick
+        sudo pkill -9 -f "$NEUTRON_ROOTWRAP-[d]aemon" || :
     fi
 }
 
diff --git a/lib/neutron_plugins/ovn_agent b/lib/neutron_plugins/ovn_agent
index dc81295..3526ccd 100644
--- a/lib/neutron_plugins/ovn_agent
+++ b/lib/neutron_plugins/ovn_agent
@@ -587,6 +587,7 @@
     rm -f $OVS_DATADIR/.*.db.~lock~
     sudo rm -f $OVN_DATADIR/*.db
     sudo rm -f $OVN_DATADIR/.*.db.~lock~
+    sudo rm -f $OVN_RUNDIR/*.sock
 }
 
 function _start_ovs {
@@ -768,7 +769,9 @@
 
 function stop_ovn {
     if is_service_enabled q-ovn-metadata-agent neutron-ovn-metadata-agent; then
-        sudo pkill -9 -f haproxy || :
+        # pkill takes care not to kill itself, but it may kill its parent
+        # sudo unless we use the "ps | grep [f]oo" trick
+        sudo pkill -9 -f "[h]aproxy" || :
         _stop_process "devstack@q-ovn-metadata-agent.service"
     fi
     if is_service_enabled ovn-controller-vtep ; then
@@ -813,5 +816,5 @@
         _cleanup $ovs_path
     fi
 
-    sudo rm -f $OVN_RUNDIR
+    sudo rm -rf $OVN_RUNDIR
 }
diff --git a/lib/neutron_plugins/services/segments b/lib/neutron_plugins/services/segments
new file mode 100644
index 0000000..08936ba
--- /dev/null
+++ b/lib/neutron_plugins/services/segments
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+function configure_segments_service_plugin {
+    neutron_service_plugin_class_add segments
+}
+
+function configure_segments_extension {
+    configure_segments_service_plugin
+}
+
diff --git a/lib/nova b/lib/nova
index 14eb8fc..3aa6b9e 100644
--- a/lib/nova
+++ b/lib/nova
@@ -490,6 +490,9 @@
         if [[ "$NOVA_ENFORCE_SCOPE" == "True" || "$ENFORCE_SCOPE" == "True" ]]; then
             iniset $NOVA_CONF oslo_policy enforce_new_defaults True
             iniset $NOVA_CONF oslo_policy enforce_scope True
+        else
+            iniset $NOVA_CONF oslo_policy enforce_new_defaults False
+            iniset $NOVA_CONF oslo_policy enforce_scope False
         fi
         if is_service_enabled tls-proxy && [ "$NOVA_USE_MOD_WSGI" == "False" ]; then
             # Set the service port for a proxy to take the original
diff --git a/lib/placement b/lib/placement
index bc22c56..c6bf99f 100644
--- a/lib/placement
+++ b/lib/placement
@@ -120,6 +120,9 @@
     if [[ "$PLACEMENT_ENFORCE_SCOPE" == "True" || "$ENFORCE_SCOPE" == "True" ]]; then
         iniset $PLACEMENT_CONF oslo_policy enforce_new_defaults True
         iniset $PLACEMENT_CONF oslo_policy enforce_scope True
+    else
+        iniset $PLACEMENT_CONF oslo_policy enforce_new_defaults False
+        iniset $PLACEMENT_CONF oslo_policy enforce_scope False
     fi
 }
 
diff --git a/lib/tempest b/lib/tempest
index 44a9b6f..7da9f17 100644
--- a/lib/tempest
+++ b/lib/tempest
@@ -128,6 +128,13 @@
         (cd $REQUIREMENTS_DIR &&
             git show master:upper-constraints.txt 2>/dev/null ||
             git show origin/master:upper-constraints.txt) > $tmp_c
+        # NOTE(gmann): we need to set the below env var pointing to master
+        # constraints even that is what default in tox.ini. Otherwise it can
+        # create the issue for grenade run where old and new devstack can have
+        # different tempest (old and master) to install. For detail problem,
+        # refer to the https://bugs.launchpad.net/devstack/+bug/2003993
+        export UPPER_CONSTRAINTS_FILE=https://releases.openstack.org/constraints/upper/master
+        export TOX_CONSTRAINTS_FILE=https://releases.openstack.org/constraints/upper/master
     else
         echo "Using $TEMPEST_VENV_UPPER_CONSTRAINTS constraints in Tempest virtual env."
         cat $TEMPEST_VENV_UPPER_CONSTRAINTS > $tmp_c
@@ -597,6 +604,10 @@
         iniset $TEMPEST_CONFIG volume storage_protocol "$TEMPEST_STORAGE_PROTOCOL"
     fi
 
+    if [[ $ENABLE_VOLUME_MULTIATTACH == "True" ]]; then
+        iniset $TEMPEST_CONFIG volume volume_type_multiattach $VOLUME_TYPE_MULTIATTACH
+    fi
+
     # Placement Features
     # Set the microversion range for placement.
     # Setting [None, latest] range of microversion which allow Tempest to run all microversions tests.
diff --git a/releasenotes/notes/Fix-dbcounter-NotImplementedError-on-SQLAlchemy-2-21bb6dcdf3ce4225.yaml b/releasenotes/notes/Fix-dbcounter-NotImplementedError-on-SQLAlchemy-2-21bb6dcdf3ce4225.yaml
new file mode 100644
index 0000000..f815e14
--- /dev/null
+++ b/releasenotes/notes/Fix-dbcounter-NotImplementedError-on-SQLAlchemy-2-21bb6dcdf3ce4225.yaml
@@ -0,0 +1,5 @@
+---
+fixes:
+  - |
+    Fixes a NotImplementedError when using the dbcounter SQLAlchemy plugin on
+    SQLAlchemy 2.x.
diff --git a/stack.sh b/stack.sh
index 28576d1..ccd2d16 100755
--- a/stack.sh
+++ b/stack.sh
@@ -394,6 +394,13 @@
     sudo dnf config-manager --set-enabled crb
     # rabbitmq and other packages are provided by RDO repositories.
     _install_rdo
+
+    # Some distributions (Rocky Linux 9) provide curl-minimal instead of curl,
+    # it triggers a conflict when devstack wants to install "curl".
+    # Swap curl-minimal with curl.
+    if is_package_installed curl-minimal; then
+        sudo dnf swap -y curl-minimal curl
+    fi
 elif [[ $DISTRO == "openEuler-22.03" ]]; then
     # There are some problem in openEuler. We should fix it first. Some required
     # package/action runs before fixup script. So we can't fix there.
diff --git a/stackrc b/stackrc
index a05d1e5..b7ce238 100644
--- a/stackrc
+++ b/stackrc
@@ -201,6 +201,11 @@
 # performance_schema that are of interest to us
 MYSQL_GATHER_PERFORMANCE=$(trueorfalse True MYSQL_GATHER_PERFORMANCE)
 
+# This can be used to reduce the amount of memory mysqld uses while running.
+# These are unscientifically determined, and could reduce performance or
+# cause other issues.
+MYSQL_REDUCE_MEMORY=$(trueorfalse False MYSQL_REDUCE_MEMORY)
+
 # Set a timeout for git operations.  If git is still running when the
 # timeout expires, the command will be retried up to 3 times.  This is
 # in the format for timeout(1);
@@ -243,7 +248,7 @@
 # Setting the variable to 'ALL' will activate the download for all
 # libraries.
 
-DEVSTACK_SERIES="2023.1"
+DEVSTACK_SERIES="2023.2"
 
 ##############
 #
diff --git a/tools/dbcounter/dbcounter.py b/tools/dbcounter/dbcounter.py
index 5057f0f..0ed7bb8 100644
--- a/tools/dbcounter/dbcounter.py
+++ b/tools/dbcounter/dbcounter.py
@@ -40,6 +40,9 @@
         self.queue = queue.Queue()
         self.thread = None
 
+    def update_url(self, url):
+        return url.difference_update_query(["dbcounter"])
+
     def engine_created(self, engine):
         """Hook the engine creation process.
 
@@ -77,12 +80,12 @@
     def do_incr(self, db, op, count):
         """Increment the counter for (db,op) by count."""
 
-        query = ('INSERT INTO queries (db, op, count) '
-                 '  VALUES (%s, %s, %s) '
-                 '  ON DUPLICATE KEY UPDATE count=count+%s')
+        query = sqlalchemy.text('INSERT INTO queries (db, op, count) '
+                                '  VALUES (:db, :op, :count) '
+                                '  ON DUPLICATE KEY UPDATE count=count+:count')
         try:
             with self.engine.begin() as conn:
-                r = conn.execute(query, (db, op, count, count))
+                r = conn.execute(query, {'db': db, 'op': op, 'count': count})
         except Exception as e:
             LOG.error('Failed to account for access to database %r: %s',
                       db, e)
diff --git a/unstack.sh b/unstack.sh
index a36af3f..33b069b 100755
--- a/unstack.sh
+++ b/unstack.sh
@@ -168,9 +168,7 @@
     cleanup_etcd3
 fi
 
-if is_service_enabled dstat; then
-    stop_dstat
-fi
+stop_dstat
 
 # NOTE: Cinder automatically installs the lvm2 package, independently of the
 # enabled backends. So if Cinder is enabled, and installed successfully we are