From 8756cb7d990fcb5735292a8fdc601af3333eb86c Mon Sep 17 00:00:00 2001 From: Ann Kamyshnikova Date: Fri, 25 Nov 2016 17:24:38 +0300 Subject: [PATCH] New enginefacade for ports and sg groups Use reader and writer for db operations. Partially-Implements blueprint: enginefacade-switch Depends-On: Iba3520ac6cfb6b82b2013df9b8e1aee64b10a11c Change-Id: I50be115ea69f805b48b02aebe4259ec2c839830e --- neutron/db/allowedaddresspairs_db.py | 6 +-- neutron/db/db_base_plugin_common.py | 8 ++- neutron/db/db_base_plugin_v2.py | 38 ++++++++------ neutron/db/extradhcpopt_db.py | 5 +- neutron/db/ipam_backend_mixin.py | 2 + neutron/db/ipam_pluggable_backend.py | 6 ++- neutron/db/portbindings_db.py | 5 +- neutron/db/securitygroups_db.py | 52 +++++++++++-------- neutron/plugins/ml2/drivers/helpers.py | 14 ++--- neutron/plugins/ml2/drivers/type_flat.py | 3 +- neutron/plugins/ml2/drivers/type_tunnel.py | 3 +- neutron/plugins/ml2/drivers/type_vlan.py | 2 +- .../tests/unit/db/test_db_base_plugin_v2.py | 16 +++--- .../unit/extensions/test_portsecurity.py | 46 ++++++++-------- .../unit/extensions/test_securitygroup.py | 7 ++- .../plugins/ml2/drivers/test_type_vlan.py | 2 + neutron/tests/unit/plugins/ml2/test_plugin.py | 4 +- 17 files changed, 125 insertions(+), 94 deletions(-) diff --git a/neutron/db/allowedaddresspairs_db.py b/neutron/db/allowedaddresspairs_db.py index 972fc00f8a6..ac123b88f6b 100644 --- a/neutron/db/allowedaddresspairs_db.py +++ b/neutron/db/allowedaddresspairs_db.py @@ -16,10 +16,10 @@ from neutron_lib.api import validators from neutron.api.v2 import attributes as attr +from neutron.common import utils from neutron.db import _resource_extend as resource_extend from neutron.db import _utils as db_utils - -from neutron.common import utils +from neutron.db import api as db_api from neutron.extensions import allowedaddresspairs as addr_pair from neutron.objects import exceptions from neutron.objects.port.extensions import (allowedaddresspairs @@ -34,7 +34,7 @@ class AllowedAddressPairsMixin(object): if not validators.is_attr_set(allowed_address_pairs): return [] try: - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): for address_pair in allowed_address_pairs: # use port.mac_address if no mac address in address pair if 'mac_address' not in address_pair: diff --git a/neutron/db/db_base_plugin_common.py b/neutron/db/db_base_plugin_common.py index f5cea2d1745..337117474af 100644 --- a/neutron/db/db_base_plugin_common.py +++ b/neutron/db/db_base_plugin_common.py @@ -27,6 +27,7 @@ from neutron.api.v2 import attributes from neutron.common import constants as n_const from neutron.common import exceptions from neutron.db import _utils as db_utils +from neutron.db import api as db_api from neutron.db import common_db_mixin from neutron.db import models_v2 from neutron.objects import subnet as subnet_obj @@ -83,6 +84,7 @@ class DbBasePluginCommon(common_db_mixin.CommonDbMixin): def _generate_mac(): return net.get_random_mac(cfg.CONF.base_mac.split(':')) + @db_api.context_manager.reader def _is_mac_in_use(self, context, network_id, mac_address): return bool(context.session.query(models_v2.Port). filter(models_v2.Port.network_id == network_id). @@ -98,7 +100,7 @@ class DbBasePluginCommon(common_db_mixin.CommonDbMixin): {'ip_address': ip_address, 'network_id': network_id, 'subnet_id': subnet_id}) - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): for ipal in (context.session.query(models_v2.IPAllocation). filter_by(network_id=network_id, ip_address=ip_address, @@ -106,6 +108,7 @@ class DbBasePluginCommon(common_db_mixin.CommonDbMixin): context.session.delete(ipal) @staticmethod + @db_api.context_manager.writer def _store_ip_allocation(context, ip_address, network_id, subnet_id, port_id): LOG.debug("Allocated IP %(ip_address)s " @@ -233,14 +236,17 @@ class DbBasePluginCommon(common_db_mixin.CommonDbMixin): return port_qry.filter_by(network_id=network_id, device_owner=constants.DEVICE_OWNER_ROUTER_GW).all() + @db_api.context_manager.reader def _get_subnets_by_network(self, context, network_id): subnet_qry = context.session.query(models_v2.Subnet) return subnet_qry.filter_by(network_id=network_id).all() + @db_api.context_manager.reader def _get_subnets_by_subnetpool(self, context, subnetpool_id): subnet_qry = context.session.query(models_v2.Subnet) return subnet_qry.filter_by(subnetpool_id=subnetpool_id).all() + @db_api.context_manager.reader def _get_all_subnets(self, context): # NOTE(salvatore-orlando): This query might end up putting # a lot of stress on the db. Consider adding a cache layer diff --git a/neutron/db/db_base_plugin_v2.py b/neutron/db/db_base_plugin_v2.py index e36c1228c47..7efa43b5993 100644 --- a/neutron/db/db_base_plugin_v2.py +++ b/neutron/db/db_base_plugin_v2.py @@ -521,12 +521,13 @@ class NeutronDbPluginV2(db_base_plugin_common.DbBasePluginCommon, # a subnet-update and a router-interface-add operation are # executed concurrently if cur_subnet and not ipv6_utils.is_ipv6_pd_enabled(s): - ipal = models_v2.IPAllocation - alloc_qry = context.session.query(ipal) - alloc_qry = alloc_qry.join("port", "routerport") - allocated = alloc_qry.filter( - ipal.ip_address == cur_subnet['gateway_ip'], - ipal.subnet_id == cur_subnet['id']).first() + with db_api.context_manager.reader.using(context): + ipal = models_v2.IPAllocation + alloc_qry = context.session.query(ipal) + alloc_qry = alloc_qry.join("port", "routerport") + allocated = alloc_qry.filter( + ipal.ip_address == cur_subnet['gateway_ip'], + ipal.subnet_id == cur_subnet['id']).first() if allocated and allocated['port_id']: raise n_exc.GatewayIpInUse( ip_address=cur_subnet['gateway_ip'], @@ -886,6 +887,7 @@ class NeutronDbPluginV2(db_base_plugin_common.DbBasePluginCommon, return result + @db_api.context_manager.reader def _subnet_get_user_allocation(self, context, subnet_id): """Check if there are any user ports on subnet and return first.""" # need to join with ports table as IPAllocation's port @@ -896,6 +898,7 @@ class NeutronDbPluginV2(db_base_plugin_common.DbBasePluginCommon, filter(~models_v2.Port.device_owner. in_(AUTO_DELETE_PORT_OWNERS)).first()) + @db_api.context_manager.reader def _subnet_check_ip_allocations_internal_router_ports(self, context, subnet_id): # Do not delete the subnet if IP allocations for internal @@ -1220,7 +1223,7 @@ class NeutronDbPluginV2(db_base_plugin_common.DbBasePluginCommon, description=p.get('description')) if p.get('mac_address') is not constants.ATTR_NOT_SPECIFIED: port_data['mac_address'] = p.get('mac_address') - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): # Ensure that the network exists. self._get_network(context, network_id) @@ -1261,7 +1264,7 @@ class NeutronDbPluginV2(db_base_plugin_common.DbBasePluginCommon, def update_port(self, context, id, port): new_port = port['port'] - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): db_port = self._get_port(context, id) new_mac = new_port.get('mac_address') self._validate_port_for_update(context, db_port, new_port, new_mac) @@ -1290,21 +1293,21 @@ class NeutronDbPluginV2(db_base_plugin_common.DbBasePluginCommon, # conflict, bubble up a retry instead that should bring things # back to sanity. raise os_db_exc.RetryRequest(e) - result = self._make_port_dict(db_port) - return result + return self._make_port_dict(db_port) @db_api.retry_if_session_inactive() def delete_port(self, context, id): - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): self.ipam.delete_port(context, id) def delete_ports_by_device_id(self, context, device_id, network_id=None): - query = (context.session.query(models_v2.Port.id) - .enable_eagerloads(False) - .filter(models_v2.Port.device_id == device_id)) - if network_id: - query = query.filter(models_v2.Port.network_id == network_id) - port_ids = [p[0] for p in query] + with db_api.context_manager.reader.using(context): + query = (context.session.query(models_v2.Port.id) + .enable_eagerloads(False) + .filter(models_v2.Port.device_id == device_id)) + if network_id: + query = query.filter(models_v2.Port.network_id == network_id) + port_ids = [p[0] for p in query] for port_id in port_ids: try: self.delete_port(context, port_id) @@ -1315,6 +1318,7 @@ class NeutronDbPluginV2(db_base_plugin_common.DbBasePluginCommon, port_id) @db_api.retry_if_session_inactive() + @db_api.context_manager.reader def get_port(self, context, id, fields=None): port = self._get_port(context, id) return self._make_port_dict(port, fields) diff --git a/neutron/db/extradhcpopt_db.py b/neutron/db/extradhcpopt_db.py index 1184bf30a9a..409fed60ef8 100644 --- a/neutron/db/extradhcpopt_db.py +++ b/neutron/db/extradhcpopt_db.py @@ -15,6 +15,7 @@ from neutron.api.v2 import attributes from neutron.db import _resource_extend as resource_extend +from neutron.db import api as db_api from neutron.extensions import extra_dhcp_opt as edo_ext from neutron.objects.port.extensions import extra_dhcp_opt as obj_extra_dhcp @@ -38,7 +39,7 @@ class ExtraDhcpOptMixin(object): extra_dhcp_opts): if not extra_dhcp_opts: return port - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): for dopt in extra_dhcp_opts: if self._is_valid_opt_value(dopt['opt_name'], dopt['opt_value']): @@ -76,7 +77,7 @@ class ExtraDhcpOptMixin(object): context, port_id=id) # if there are currently no dhcp_options associated to # this port, Then just insert the new ones and be done. - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): for upd_rec in dopts: for opt in opts: if (opt['opt_name'] == upd_rec['opt_name'] diff --git a/neutron/db/ipam_backend_mixin.py b/neutron/db/ipam_backend_mixin.py index 385a6a5973f..a69728adb15 100644 --- a/neutron/db/ipam_backend_mixin.py +++ b/neutron/db/ipam_backend_mixin.py @@ -34,6 +34,7 @@ from neutron.common import exceptions as n_exc from neutron.common import ipv6_utils from neutron.common import utils as common_utils from neutron.db import _utils as db_utils +from neutron.db import api as db_api from neutron.db import db_base_plugin_common from neutron.db.models import segment as segment_model from neutron.db.models import subnet_service_type as sst_model @@ -162,6 +163,7 @@ class IpamBackendMixin(db_base_plugin_common.DbBasePluginCommon): del s["dns_nameservers"] return new_dns_addr_list + @db_api.context_manager.writer def _update_subnet_allocation_pools(self, context, subnet_id, s): context.session.query(models_v2.IPAllocationPool).filter_by( subnet_id=subnet_id).delete() diff --git a/neutron/db/ipam_pluggable_backend.py b/neutron/db/ipam_pluggable_backend.py index d89b2a6a87d..d051d1241a8 100644 --- a/neutron/db/ipam_pluggable_backend.py +++ b/neutron/db/ipam_pluggable_backend.py @@ -27,6 +27,7 @@ from sqlalchemy import and_ from neutron._i18n import _LE, _LW from neutron.common import constants as n_const from neutron.common import ipv6_utils +from neutron.db import api as db_api from neutron.db import ipam_backend_mixin from neutron.db import models_v2 from neutron.ipam import driver @@ -304,6 +305,7 @@ class IpamPluggableBackend(ipam_backend_mixin.IpamBackendMixin): original=changes.original, remove=removed) + @db_api.context_manager.writer def save_allocation_pools(self, context, subnet, allocation_pools): for pool in allocation_pools: first_ip = str(netaddr.IPAddress(pool.first, pool.version)) @@ -406,6 +408,8 @@ class IpamPluggableBackend(ipam_backend_mixin.IpamBackendMixin): raise RuntimeError( "Subnet manager doesn't match subnet. %s != %s" % (subnet['id'], ipam_subnet.subnet_manager.neutron_id)) + # TODO(ataraday): switched for writer when flush_on_subtransaction + # will be available for neutron with context.session.begin(subtransactions=True): network_id = subnet['network_id'] port_qry = context.session.query(models_v2.Port) @@ -436,7 +440,7 @@ class IpamPluggableBackend(ipam_backend_mixin.IpamBackendMixin): # the context of a nested transaction, so that the entry # is rolled back independently of other entries whenever # the corresponding port has been deleted. - with context.session.begin_nested(): + with db_api.context_manager.writer.using(context): context.session.add(allocated) updated_ports.append(port['id']) except db_exc.DBReferenceError: diff --git a/neutron/db/portbindings_db.py b/neutron/db/portbindings_db.py index 1bb43351c7f..677be381916 100644 --- a/neutron/db/portbindings_db.py +++ b/neutron/db/portbindings_db.py @@ -19,6 +19,7 @@ from neutron_lib.api import validators from neutron.api.v2 import attributes from neutron.db import _model_query as model_query from neutron.db import _resource_extend as resource_extend +from neutron.db import api as db_api from neutron.db.models import portbinding as pmodels from neutron.db import models_v2 from neutron.db import portbindings_base @@ -65,7 +66,7 @@ class PortBindingMixin(portbindings_base.PortBindingBaseMixin): host = port_data.get(portbindings.HOST_ID) host_set = validators.is_attr_set(host) - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): bind_port = context.session.query( pmodels.PortBindingPort).filter_by(port_id=port['id']).first() if host_set: @@ -79,7 +80,7 @@ class PortBindingMixin(portbindings_base.PortBindingBaseMixin): self._extend_port_dict_binding_host(port, host) def get_port_host(self, context, port_id): - with context.session.begin(subtransactions=True): + with db_api.context_manager.reader.using(context): bind_port = ( context.session.query(pmodels.PortBindingPort). filter_by(port_id=port_id). diff --git a/neutron/db/securitygroups_db.py b/neutron/db/securitygroups_db.py index 663e0b6d5f9..ad89b6cb7c2 100644 --- a/neutron/db/securitygroups_db.py +++ b/neutron/db/securitygroups_db.py @@ -84,7 +84,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase): # default already exists, return it return self.get_security_group(context, existing_def_sg_id) - with db_api.autonested_transaction(context.session): + with db_api.context_manager.writer.using(context): security_group_db = sg_models.SecurityGroup(id=s.get('id') or ( uuidutils.generate_uuid()), description=s['description'], @@ -167,7 +167,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase): context.tenant_id = tenant_id try: - with context.session.begin(subtransactions=True): + with db_api.context_manager.reader.using(context): ret = self._make_security_group_dict(self._get_security_group( context, id), fields) ret['security_group_rules'] = self.get_security_group_rules( @@ -189,26 +189,33 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase): @db_api.retry_if_session_inactive() def delete_security_group(self, context, id): filters = {'security_group_id': [id]} - ports = self._get_port_security_group_bindings(context, filters) - if ports: - raise ext_sg.SecurityGroupInUse(id=id) - # confirm security group exists - sg = self._get_security_group(context, id) + with db_api.context_manager.reader.using(context): + ports = self._get_port_security_group_bindings(context, filters) + if ports: + raise ext_sg.SecurityGroupInUse(id=id) + # confirm security group exists + sg = self._get_security_group(context, id) - if sg['name'] == 'default' and not context.is_admin: - raise ext_sg.SecurityGroupCannotRemoveDefault() + if sg['name'] == 'default' and not context.is_admin: + raise ext_sg.SecurityGroupCannotRemoveDefault() kwargs = { 'context': context, 'security_group_id': id, 'security_group': sg, } - self._registry_notify(resources.SECURITY_GROUP, events.BEFORE_DELETE, + self._registry_notify(resources.SECURITY_GROUP, + events.BEFORE_DELETE, exc_cls=ext_sg.SecurityGroupInUse, id=id, **kwargs) - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): # pass security_group_rule_ids to ensure # consistency with deleted rules + # get security_group_bindings and security_group one more time + # so that they will be attached for session where sg will be + # deleted + ports = self._get_port_security_group_bindings(context, filters) + sg = self._get_security_group(context, id) kwargs['security_group_rule_ids'] = [r['id'] for r in sg.rules] self._registry_notify(resources.SECURITY_GROUP, events.PRECOMMIT_DELETE, @@ -217,8 +224,8 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase): context.session.delete(sg) kwargs.pop('security_group') - registry.notify(resources.SECURITY_GROUP, events.AFTER_DELETE, self, - **kwargs) + registry.notify(resources.SECURITY_GROUP, events.AFTER_DELETE, + self, **kwargs) @db_api.retry_if_session_inactive() def update_security_group(self, context, id, security_group): @@ -232,7 +239,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase): self._registry_notify(resources.SECURITY_GROUP, events.BEFORE_UPDATE, exc_cls=ext_sg.SecurityGroupConflict, **kwargs) - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): sg = self._get_security_group(context, id) if sg['name'] == 'default' and 'name' in s: raise ext_sg.SecurityGroupCannotUpdateDefault() @@ -268,7 +275,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase): @db_api.retry_if_session_inactive() def _create_port_security_group_binding(self, context, port_id, security_group_id): - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): db = sg_models.SecurityGroupPortBinding(port_id=port_id, security_group_id=security_group_id) context.session.add(db) @@ -282,10 +289,11 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase): @db_api.retry_if_session_inactive() def _delete_port_security_group_bindings(self, context, port_id): - query = self._model_query(context, sg_models.SecurityGroupPortBinding) - bindings = query.filter( - sg_models.SecurityGroupPortBinding.port_id == port_id) - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): + query = self._model_query(context, + sg_models.SecurityGroupPortBinding) + bindings = query.filter( + sg_models.SecurityGroupPortBinding.port_id == port_id) for binding in bindings: context.session.delete(binding) @@ -301,7 +309,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase): scoped_session(context.session) security_group_id = self._validate_security_group_rules( context, security_group_rules) - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): if not self.get_security_group(context, security_group_id): raise ext_sg.SecurityGroupNotFound(id=security_group_id) @@ -338,7 +346,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase): events.BEFORE_CREATE, exc_cls=ext_sg.SecurityGroupConflict, **kwargs) - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): if validate: self._check_for_duplicate_rules_in_db(context, security_group_rule) @@ -630,7 +638,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase): events.BEFORE_DELETE, id=id, exc_cls=ext_sg.SecurityGroupRuleInUse, **kwargs) - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): query = self._model_query(context, sg_models.SecurityGroupRule).filter( sg_models.SecurityGroupRule.id == id) diff --git a/neutron/plugins/ml2/drivers/helpers.py b/neutron/plugins/ml2/drivers/helpers.py index 91dc3ccd088..7f4fd2cef11 100644 --- a/neutron/plugins/ml2/drivers/helpers.py +++ b/neutron/plugins/ml2/drivers/helpers.py @@ -23,6 +23,7 @@ from oslo_log import log from neutron._i18n import _LE from neutron.common import exceptions as exc +from neutron.db import api as db_api from neutron.plugins.common import utils as p_utils from neutron.plugins.ml2 import driver_api as api @@ -64,8 +65,8 @@ class SegmentTypeDriver(BaseTypeDriver): # TODO(ataraday): get rid of this method when old TypeDriver won't be used def _get_session(self, arg): if isinstance(arg, neutron_ctx.Context): - return arg.session - return arg + return arg.session, db_api.context_manager.writer.using(arg) + return arg, arg.session.begin(subtransactions=True) def allocate_fully_specified_segment(self, context, **raw_segment): """Allocate segment fully specified by raw_segment. @@ -76,9 +77,10 @@ class SegmentTypeDriver(BaseTypeDriver): """ network_type = self.get_type() - session = self._get_session(context) + session, ctx_manager = self._get_session(context) + try: - with session.begin(subtransactions=True): + with ctx_manager: alloc = ( session.query(self.model).filter_by(**raw_segment). first()) @@ -132,8 +134,8 @@ class SegmentTypeDriver(BaseTypeDriver): """ network_type = self.get_type() - session = self._get_session(context) - with session.begin(subtransactions=True): + session, ctx_manager = self._get_session(context) + with ctx_manager: select = (session.query(self.model). filter_by(allocated=False, **filters)) diff --git a/neutron/plugins/ml2/drivers/type_flat.py b/neutron/plugins/ml2/drivers/type_flat.py index 951591081cc..0c9cf587ab2 100644 --- a/neutron/plugins/ml2/drivers/type_flat.py +++ b/neutron/plugins/ml2/drivers/type_flat.py @@ -21,6 +21,7 @@ import six from neutron._i18n import _, _LI, _LW from neutron.common import exceptions as n_exc from neutron.conf.plugins.ml2.drivers import driver_type +from neutron.db import api as db_api from neutron.objects import exceptions as obj_base from neutron.objects.plugins.ml2 import flatallocation as flat_obj from neutron.plugins.common import constants as p_const @@ -107,7 +108,7 @@ class FlatTypeDriver(helpers.BaseTypeDriver): def release_segment(self, context, segment): physical_network = segment[api.PHYSICAL_NETWORK] - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): obj = flat_obj.FlatAllocation.get_object( context, physical_network=physical_network) diff --git a/neutron/plugins/ml2/drivers/type_tunnel.py b/neutron/plugins/ml2/drivers/type_tunnel.py index 3e8974f7ac6..cb6e076fb06 100644 --- a/neutron/plugins/ml2/drivers/type_tunnel.py +++ b/neutron/plugins/ml2/drivers/type_tunnel.py @@ -311,7 +311,7 @@ class ML2TunnelTypeDriver(_TunnelTypeDriverBase): inside = any(lo <= tunnel_id <= hi for lo, hi in self.tunnel_ranges) info = {'type': self.get_type(), 'id': tunnel_id} - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): query = (context.session.query(self.model). filter_by(**{self.segmentation_key: tunnel_id})) if inside: @@ -328,6 +328,7 @@ class ML2TunnelTypeDriver(_TunnelTypeDriverBase): if not count: LOG.warning(_LW("%(type)s tunnel %(id)s not found"), info) + @db_api.context_manager.reader def get_allocation(self, context, tunnel_id): return (context.session.query(self.model). filter_by(**{self.segmentation_key: tunnel_id}). diff --git a/neutron/plugins/ml2/drivers/type_vlan.py b/neutron/plugins/ml2/drivers/type_vlan.py index 0bb08d3a69c..4b5b2923b41 100644 --- a/neutron/plugins/ml2/drivers/type_vlan.py +++ b/neutron/plugins/ml2/drivers/type_vlan.py @@ -211,7 +211,7 @@ class VlanTypeDriver(helpers.SegmentTypeDriver): ranges = self.network_vlan_ranges.get(physical_network, []) inside = any(lo <= vlan_id <= hi for lo, hi in ranges) - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): query = (context.session.query(vlan_alloc_model.VlanAllocation). filter_by(physical_network=physical_network, vlan_id=vlan_id)) diff --git a/neutron/tests/unit/db/test_db_base_plugin_v2.py b/neutron/tests/unit/db/test_db_base_plugin_v2.py index 7e385892468..962b887599b 100644 --- a/neutron/tests/unit/db/test_db_base_plugin_v2.py +++ b/neutron/tests/unit/db/test_db_base_plugin_v2.py @@ -4490,10 +4490,10 @@ class TestSubnetsV2(NeutronDbPluginV2TestCase): # this protection only applies to router ports so we need # to make this port belong to a router ctx = context.get_admin_context() - with ctx.session.begin(): + with db_api.context_manager.writer.using(ctx): router = l3_models.Router() ctx.session.add(router) - with ctx.session.begin(): + with db_api.context_manager.writer.using(ctx): rp = l3_models.RouterPort(router_id=router.id, port_id=port['port']['id']) ctx.session.add(rp) @@ -4503,7 +4503,7 @@ class TestSubnetsV2(NeutronDbPluginV2TestCase): res = req.get_response(self.api) self.assertEqual(409, res.status_int) # should work fine if it's not a router port - with ctx.session.begin(): + with db_api.context_manager.writer.using(ctx): ctx.session.delete(rp) ctx.session.delete(router) res = req.get_response(self.api) @@ -6104,7 +6104,7 @@ class DbModelMixin(object): self.assertEqual(final_exp, actual_repr_output) def _make_security_group_and_rule(self, ctx): - with ctx.session.begin(): + with db_api.context_manager.writer.using(ctx): sg = sg_models.SecurityGroup(name='sg', description='sg') rule = sg_models.SecurityGroupRule( security_group=sg, port_range_min=1, @@ -6116,7 +6116,7 @@ class DbModelMixin(object): return sg, rule def _make_floating_ip(self, ctx, port_id): - with ctx.session.begin(): + with db_api.context_manager.writer.using(ctx): flip = l3_models.FloatingIP(floating_ip_address='1.2.3.4', floating_network_id='somenet', floating_port_id=port_id) @@ -6124,7 +6124,7 @@ class DbModelMixin(object): return flip def _make_router(self, ctx): - with ctx.session.begin(): + with db_api.context_manager.writer.using(ctx): router = l3_models.Router() ctx.session.add(router) return router @@ -6207,7 +6207,7 @@ class DbModelMixin(object): def _lock_blocked_name_update(): ctx = context.get_admin_context() - with ctx.session.begin(): + with db_api.context_manager.writer.using(ctx): thing = ctx.session.query(model).filter_by(id=dbid).one() thing.bump_revision() thing.name = 'newname' @@ -6222,7 +6222,7 @@ class DbModelMixin(object): while not self._blocked_on_lock: eventlet.sleep(0) ctx = context.get_admin_context() - with ctx.session.begin(): + with db_api.context_manager.writer.using(ctx): thing = ctx.session.query(model).filter_by(id=dbid).one() thing.bump_revision() thing.description = 'a description' diff --git a/neutron/tests/unit/extensions/test_portsecurity.py b/neutron/tests/unit/extensions/test_portsecurity.py index 7b4080bac5c..ea17b53ace7 100644 --- a/neutron/tests/unit/extensions/test_portsecurity.py +++ b/neutron/tests/unit/extensions/test_portsecurity.py @@ -19,6 +19,7 @@ from neutron_lib.plugins import directory from webob import exc from neutron.db import _utils as db_utils +from neutron.db import api as db_api from neutron.db import db_base_plugin_v2 from neutron.db import portsecurity_db from neutron.db import securitygroups_db @@ -59,7 +60,7 @@ class PortSecurityTestPlugin(db_base_plugin_v2.NeutronDbPluginV2, def create_network(self, context, network): tenant_id = network['network'].get('tenant_id') self._ensure_default_security_group(context, tenant_id) - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): neutron_db = super(PortSecurityTestPlugin, self).create_network( context, network) neutron_db.update(network['network']) @@ -68,7 +69,7 @@ class PortSecurityTestPlugin(db_base_plugin_v2.NeutronDbPluginV2, return neutron_db def update_network(self, context, id, network): - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): neutron_db = super(PortSecurityTestPlugin, self).update_network( context, id, network) if psec.PORTSECURITY in network['network']: @@ -77,36 +78,35 @@ class PortSecurityTestPlugin(db_base_plugin_v2.NeutronDbPluginV2, return neutron_db def get_network(self, context, id, fields=None): - with context.session.begin(subtransactions=True): + with db_api.context_manager.reader.using(context): net = super(PortSecurityTestPlugin, self).get_network( context, id) return db_utils.resource_fields(net, fields) def create_port(self, context, port): p = port['port'] - with context.session.begin(subtransactions=True): - p[ext_sg.SECURITYGROUPS] = self._get_security_groups_on_port( - context, port) - neutron_db = super(PortSecurityTestPlugin, self).create_port( - context, port) - p.update(neutron_db) + p[ext_sg.SECURITYGROUPS] = self._get_security_groups_on_port( + context, port) + neutron_db = super(PortSecurityTestPlugin, self).create_port( + context, port) + p.update(neutron_db) - (port_security, has_ip) = self._determine_port_security_and_has_ip( - context, p) - p[psec.PORTSECURITY] = port_security - self._process_port_port_security_create(context, p, neutron_db) + (port_security, has_ip) = self._determine_port_security_and_has_ip( + context, p) + p[psec.PORTSECURITY] = port_security + self._process_port_port_security_create(context, p, neutron_db) - if (validators.is_attr_set(p.get(ext_sg.SECURITYGROUPS)) and - not (port_security and has_ip)): - raise psec.PortSecurityAndIPRequiredForSecurityGroups() + if (validators.is_attr_set(p.get(ext_sg.SECURITYGROUPS)) and + not (port_security and has_ip)): + raise psec.PortSecurityAndIPRequiredForSecurityGroups() - # Port requires ip and port_security enabled for security group - if has_ip and port_security: - self._ensure_default_security_group_on_port(context, port) + # Port requires ip and port_security enabled for security group + if has_ip and port_security: + self._ensure_default_security_group_on_port(context, port) - if (p.get(ext_sg.SECURITYGROUPS) and p[psec.PORTSECURITY]): - self._process_port_create_security_group( - context, p, p[ext_sg.SECURITYGROUPS]) + if (p.get(ext_sg.SECURITYGROUPS) and p[psec.PORTSECURITY]): + self._process_port_create_security_group( + context, p, p[ext_sg.SECURITYGROUPS]) return port['port'] @@ -114,7 +114,7 @@ class PortSecurityTestPlugin(db_base_plugin_v2.NeutronDbPluginV2, delete_security_groups = self._check_update_deletes_security_groups( port) has_security_groups = self._check_update_has_security_groups(port) - with context.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): ret_port = super(PortSecurityTestPlugin, self).update_port( context, id, port) # copy values over - but not fixed_ips diff --git a/neutron/tests/unit/extensions/test_securitygroup.py b/neutron/tests/unit/extensions/test_securitygroup.py index 0e238180c39..c3f6abd0acf 100644 --- a/neutron/tests/unit/extensions/test_securitygroup.py +++ b/neutron/tests/unit/extensions/test_securitygroup.py @@ -28,6 +28,7 @@ import webob.exc from neutron.api.v2 import attributes as attr from neutron.common import exceptions as n_exc +from neutron.db import api as db_api from neutron.db import db_base_plugin_v2 from neutron.db import securitygroups_db from neutron.extensions import securitygroup as ext_sg @@ -203,8 +204,7 @@ class SecurityGroupTestPlugin(db_base_plugin_v2.NeutronDbPluginV2, default_sg = self._ensure_default_security_group(context, tenant_id) if not validators.is_attr_set(port['port'].get(ext_sg.SECURITYGROUPS)): port['port'][ext_sg.SECURITYGROUPS] = [default_sg] - session = context.session - with session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): sgids = self._get_security_groups_on_port(context, port) port = super(SecurityGroupTestPlugin, self).create_port(context, port) @@ -213,8 +213,7 @@ class SecurityGroupTestPlugin(db_base_plugin_v2.NeutronDbPluginV2, return port def update_port(self, context, id, port): - session = context.session - with session.begin(subtransactions=True): + with db_api.context_manager.writer.using(context): if ext_sg.SECURITYGROUPS in port['port']: port['port'][ext_sg.SECURITYGROUPS] = ( self._get_security_groups_on_port(context, port)) diff --git a/neutron/tests/unit/plugins/ml2/drivers/test_type_vlan.py b/neutron/tests/unit/plugins/ml2/drivers/test_type_vlan.py index a6a9189e148..68bff7e8a22 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/test_type_vlan.py +++ b/neutron/tests/unit/plugins/ml2/drivers/test_type_vlan.py @@ -18,6 +18,7 @@ from neutron_lib import context from neutron_lib import exceptions as exc from testtools import matchers +from neutron.db import api as db_api from neutron.db.models.plugins.ml2 import vlanallocation as vlan_alloc_model from neutron.plugins.common import constants as p_const from neutron.plugins.common import utils as plugin_utils @@ -59,6 +60,7 @@ class VlanTypeTest(testlib_api.SqlTestCase): self.assertRaises(SystemExit, self.driver._parse_network_vlan_ranges) + @db_api.context_manager.reader def _get_allocation(self, context, segment): return context.session.query( vlan_alloc_model.VlanAllocation).filter_by( diff --git a/neutron/tests/unit/plugins/ml2/test_plugin.py b/neutron/tests/unit/plugins/ml2/test_plugin.py index 880ae4baf51..7e58fe7beeb 100644 --- a/neutron/tests/unit/plugins/ml2/test_plugin.py +++ b/neutron/tests/unit/plugins/ml2/test_plugin.py @@ -2440,14 +2440,14 @@ class TestTransactionGuard(Ml2PluginV2TestCase): def test_delete_network_guard(self): plugin = directory.get_plugin() ctx = context.get_admin_context() - with ctx.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(ctx): with testtools.ExpectedException(RuntimeError): plugin.delete_network(ctx, 'id') def test_delete_subnet_guard(self): plugin = directory.get_plugin() ctx = context.get_admin_context() - with ctx.session.begin(subtransactions=True): + with db_api.context_manager.writer.using(ctx): with testtools.ExpectedException(RuntimeError): plugin.delete_subnet(ctx, 'id')