Fix bug with changing offloading modes for bonds
* Change offloading_modes field in DB model to mutable * Manually mark it as 'changed' after changing modes * Add MutableList class (TMP. Till it will be added in sqlalchemy.) Closes-bug: #1480169 Change-Id: I0f5f3d195540777e449a6bacba67991afcc32f3d
This commit is contained in:
parent
e390cf8701
commit
62a1a7e5ec
|
@ -0,0 +1,54 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright 2015 Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from sqlalchemy.ext.mutable import Mutable
|
||||
|
||||
|
||||
class MutableList(Mutable, list):
|
||||
# TODO(fzhadaev): delete this class after it will be
|
||||
# implemented in sqlalchemy lib.
|
||||
# https://bitbucket.org/zzzeek/sqlalchemy/issues/3297
|
||||
|
||||
@classmethod
|
||||
def coerce(cls, key, value):
|
||||
"""Convert plain lists to MutableList."""
|
||||
|
||||
if not isinstance(value, MutableList):
|
||||
if isinstance(value, list):
|
||||
return MutableList(value)
|
||||
|
||||
# this call will raise ValueError
|
||||
return Mutable.coerce(key, value)
|
||||
else:
|
||||
return value
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
"""Detect list set events and emit change events."""
|
||||
|
||||
list.__setitem__(self, key, value)
|
||||
self.changed()
|
||||
|
||||
def __delitem__(self, key):
|
||||
"""Detect list del events and emit change events."""
|
||||
|
||||
list.__delitem__(self, key)
|
||||
self.changed()
|
||||
|
||||
def __getstate__(self):
|
||||
return list(self)
|
||||
|
||||
def __setstate__(self, state):
|
||||
self[:] = state
|
|
@ -33,6 +33,7 @@ from nailgun import consts
|
|||
from nailgun.db.sqlalchemy.models.base import Base
|
||||
from nailgun.db.sqlalchemy.models.fields import JSON
|
||||
from nailgun.db.sqlalchemy.models.fields import LowercaseString
|
||||
from nailgun.db.sqlalchemy.models.mutable import MutableList
|
||||
from nailgun.db.sqlalchemy.models.network import NetworkBondAssignment
|
||||
from nailgun.db.sqlalchemy.models.network import NetworkNICAssignment
|
||||
from nailgun.extensions.volume_manager.manager import VolumeManager
|
||||
|
@ -266,7 +267,8 @@ class NodeNICInterface(Base):
|
|||
bus_info = Column(Text)
|
||||
pxe = Column(Boolean, default=False, nullable=False)
|
||||
|
||||
offloading_modes = Column(JSON, default=[], nullable=False,
|
||||
offloading_modes = Column(MutableList.as_mutable(JSON),
|
||||
default=[], nullable=False,
|
||||
server_default='[]')
|
||||
|
||||
@property
|
||||
|
@ -377,6 +379,7 @@ class NodeBondInterface(Base):
|
|||
NodeNICInterface.offloading_modes_as_flat_dict(new_modes)
|
||||
for interface in self.slaves:
|
||||
self._update_modes(interface.offloading_modes, new_modes_dict)
|
||||
interface.offloading_modes.changed()
|
||||
|
||||
def _update_modes(self, modes, update_dict):
|
||||
for mode in modes:
|
||||
|
|
|
@ -782,6 +782,9 @@ class NetworkManager(object):
|
|||
node_id=node_db.id
|
||||
).first()
|
||||
)
|
||||
|
||||
bond_db.offloading_modes = bond.get('offloading_modes', {})
|
||||
|
||||
db().commit()
|
||||
|
||||
return node_db.id
|
||||
|
|
|
@ -613,3 +613,45 @@ class TestNodeNICsBonding(BaseIntegrationTest):
|
|||
"and doesn't contain node's pxe interface 'eth0'".format(
|
||||
self.env.nodes[0]["id"])
|
||||
)
|
||||
|
||||
def test_nics_bond_change_offloading_modes(self):
|
||||
self.get_node_nics_info()
|
||||
self.nics_bond_create(self.put_single)
|
||||
resp = self.app.get(
|
||||
reverse("NodeNICsHandler",
|
||||
kwargs={"node_id": self.env.nodes[0]["id"]}),
|
||||
headers=self.default_headers)
|
||||
|
||||
self.assertEqual(200, resp.status_code)
|
||||
body = resp.json_body
|
||||
bonds = filter(
|
||||
lambda iface: iface["type"] == NETWORK_INTERFACE_TYPES.bond,
|
||||
body)
|
||||
self.assertEqual(1, len(bonds))
|
||||
|
||||
bond_offloading_modes = bonds[0]['offloading_modes']
|
||||
self.assertEqual(len(bond_offloading_modes), 1)
|
||||
slaves = bonds[0]['slaves']
|
||||
|
||||
self.assertEqual(2, len(slaves))
|
||||
|
||||
self.assertIsNone(bond_offloading_modes[0]['state'])
|
||||
bond_offloading_modes[0]['state'] = True
|
||||
self.assertTrue(bond_offloading_modes[0]['state'])
|
||||
|
||||
resp = self.env.node_nics_put(
|
||||
self.env.nodes[0]["id"],
|
||||
body)
|
||||
|
||||
body = resp.json_body
|
||||
bonds = filter(
|
||||
lambda iface: iface["type"] == NETWORK_INTERFACE_TYPES.bond,
|
||||
body)
|
||||
self.assertEqual(1, len(bonds))
|
||||
|
||||
bond_offloading_modes = bonds[0]['offloading_modes']
|
||||
self.assertEqual(len(bond_offloading_modes), 1)
|
||||
slaves = bonds[0]['slaves']
|
||||
|
||||
self.assertEqual(2, len(slaves))
|
||||
self.assertTrue(bond_offloading_modes[0]['state'])
|
||||
|
|
Loading…
Reference in New Issue