Merge "deepcopy binding and binding levels avoid expiration"

This commit is contained in:
Jenkins 2017-04-07 23:54:37 +00:00 committed by Gerrit Code Review
commit cb577fc862
4 changed files with 24 additions and 7 deletions

View File

@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import copy
from neutron_lib.api.definitions import portbindings
from neutron_lib import constants
from oslo_log import log
@ -95,8 +97,10 @@ class PortContext(MechanismDriverContext, api.PortContext):
self._original_port = original_port
self._network_context = NetworkContext(plugin, plugin_context,
network) if network else None
self._binding = binding
self._binding_levels = binding_levels
# NOTE(kevinbenton): these copys can go away once we are working with
# OVO objects here instead of native SQLA objects.
self._binding = copy.deepcopy(binding)
self._binding_levels = copy.deepcopy(binding_levels)
self._segments_to_bind = None
self._new_bound_segment = None
self._next_segments_to_bind = None

View File

@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import copy
from eventlet import greenthread
from neutron_lib.api.definitions import portbindings
from neutron_lib.api.definitions import provider_net
@ -339,6 +341,10 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
binding.host = ''
self._update_port_dict_binding(port, binding)
# merging here brings binding changes into the session so they can be
# committed since the binding attached to the context is detached from
# the session
plugin_context.session.merge(binding)
return changes
@db_api.retry_db_errors
@ -507,6 +513,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
cur_binding.host)
db.set_binding_levels(plugin_context,
bind_context._binding_levels)
# refresh context with a snapshot of updated state
cur_context._binding = copy.deepcopy(cur_binding)
cur_context._binding_levels = bind_context._binding_levels
# Update PortContext's port dictionary to reflect the
@ -1343,6 +1351,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
self._update_port_dict_binding(port, binding)
binding.host = attrs and attrs.get(portbindings.HOST_ID)
binding.router_id = attrs and attrs.get('device_id')
# merge into session to reflect changes
plugin_context.session.merge(binding)
@utils.transaction_guard
@db_api.retry_if_session_inactive()
@ -1563,8 +1573,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
context, port['id'], host)
if not binding:
return
binding['status'] = status
binding.update(binding)
binding.status = status
updated = True
if (updated and

View File

@ -1606,7 +1606,8 @@ class TestMl2PortBinding(Ml2PluginV2TestCase,
plugin = directory.get_plugin()
binding = plugin._get_port(
self.context, port['port']['id']).port_binding
binding['host'] = 'test'
with self.context.session.begin(subtransactions=True):
binding.host = 'test'
mech_context = driver_context.PortContext(
plugin, self.context, port['port'],
plugin.get_network(self.context, port['port']['network_id']),
@ -1614,7 +1615,9 @@ class TestMl2PortBinding(Ml2PluginV2TestCase,
with mock.patch('neutron.plugins.ml2.plugin.Ml2Plugin.'
'_update_port_dict_binding') as update_mock:
attrs = {portbindings.HOST_ID: None}
plugin._process_port_binding(mech_context, attrs)
self.assertEqual('test', binding.host)
with self.context.session.begin(subtransactions=True):
plugin._process_port_binding(mech_context, attrs)
self.assertTrue(update_mock.mock_calls)
self.assertEqual('', binding.host)

View File

@ -18,6 +18,7 @@ from neutron_lib.api.definitions import portbindings
from neutron_lib import constants as const
from neutron_lib import context
from neutron_lib.plugins import directory
from oslo_serialization import jsonutils
from neutron.conf.plugins.ml2.drivers import driver_type
from neutron.plugins.ml2 import config
@ -201,7 +202,7 @@ class PortBindingTestCase(test_plugin.NeutronDbPluginV2TestCase):
port_id=original_port['id'],
host=original_port['binding:host_id'],
vnic_type=original_port['binding:vnic_type'],
profile=original_port['binding:profile'],
profile=jsonutils.dumps(original_port['binding:profile']),
vif_type=original_port['binding:vif_type'],
vif_details=original_port['binding:vif_details'])
levels = 1