Add preserve_on_delete to server nic object

This field will indicate whether we should delete or unbind the
port during server deletion or detaching interfaces.

Change-Id: I25834a82b83806bf87b4c7006a8d33d56e2ce976
Closes-Bug: #1715040
This commit is contained in:
Zhenguo Niu 2017-09-08 11:52:20 +08:00
parent ba2aeab9dd
commit 1c50ceed0b
9 changed files with 50 additions and 11 deletions

View File

@ -117,6 +117,13 @@ class Connection(object):
This delete a nic db entry.
"""
@abc.abstractmethod
def server_nic_get(self, context, port_id):
"""Get a nic db entry.
This gets a nic db entry.
"""
# Servers Faults
@abc.abstractmethod
def server_fault_create(self, context, values):

View File

@ -102,6 +102,7 @@ def upgrade():
sa.Column('network_id', sa.String(length=36), nullable=True),
sa.Column('floating_ip', sa.String(length=64), nullable=True),
sa.Column('fixed_ips', sa.Text(), nullable=True),
sa.Column('preserve_on_delete', sa.Boolean(), nullable=True),
sa.PrimaryKeyConstraint('port_id'),
sa.Index('server_nics_server_uuid_idx', 'server_uuid'),
mysql_ENGINE='InnoDB',

View File

@ -344,6 +344,14 @@ class Connection(api.Connection):
if count != 1:
raise exception.PortNotFound(port_id=port_id)
def server_nic_get(self, context, port_id):
query = model_query(context, models.ServerNic).filter_by(
port_id=port_id)
try:
return query.one()
except NoResultFound:
raise exception.PortNotFound(port_id=port_id)
@oslo_db_api.retry_on_deadlock
def server_nic_update_or_create(self, context, port_id, values):
with _session_for_write() as session:

View File

@ -110,6 +110,7 @@ class ServerNic(Base):
network_id = Column(String(36), nullable=True)
fixed_ips = Column(db_types.JsonEncodedList)
floating_ip = Column(String(64), nullable=True)
preserve_on_delete = Column(Boolean)
_server = orm.relationship(
Server,
backref=orm.backref('server_nics', uselist=False),

View File

@ -154,6 +154,7 @@ class BuildNetworkTask(flow_utils.MoganTask):
if vif.get('net_id'):
port = self.manager.network_api.create_port(
context, vif['net_id'], server.uuid)
preserve_on_delete = False
elif vif.get('port_id'):
port = self.manager.network_api.show_port(
context, vif.get('port_id'))
@ -161,11 +162,13 @@ class BuildNetworkTask(flow_utils.MoganTask):
self.manager.network_api.bind_port(context,
port['id'],
server)
preserve_on_delete = True
nic_dict = {'port_id': port['id'],
'network_id': port['network_id'],
'mac_address': port['mac_address'],
'fixed_ips': port['fixed_ips'],
'preserve_on_delete': preserve_on_delete,
'server_uuid': server.uuid}
server_nic = objects.ServerNic(context, **nic_dict)

View File

@ -289,9 +289,9 @@ class EngineManager(base_manager.BaseEngineManager):
server.save()
def destroy_networks(self, context, server):
ports = server.nics.get_port_ids()
for port in ports:
self._detach_interface(context, server, port)
for nic in server.nics:
self._detach_interface(context, server, nic.port_id,
nic.preserve_on_delete)
def _rollback_servers_quota(self, context, number):
reserve_opts = {'servers': number}
@ -582,24 +582,28 @@ class EngineManager(base_manager.BaseEngineManager):
vif_port = self.network_api.show_port(context, port_id)
except Exception:
raise exception.PortNotFound(port_id=port_id)
self.network_api.check_port_availability(vif_port)
try:
self.network_api.check_port_availability(vif_port)
self.network_api.bind_port(context, port_id, server)
except Exception as e:
raise exception.InterfaceAttachFailed(message=six.text_type(e))
preserve_on_delete = True
else:
LOG.debug("Attaching network interface %(net_id) to server "
"%(server)s", {'net_id': net_id, 'server': server})
vif_port = self.network_api.create_port(context, net_id,
server.uuid)
preserve_on_delete = False
try:
vif = self.network_api.bind_port(context, vif_port['id'], server)
vif_port = vif['port']
self.driver.plug_vif(server.node_uuid, vif_port['id'])
nics_obj = objects.ServerNics(context)
nic_dict = {'port_id': vif_port['id'],
'network_id': vif_port['network_id'],
'mac_address': vif_port['mac_address'],
'fixed_ips': vif_port['fixed_ips'],
'preserve_on_delete': preserve_on_delete,
'server_uuid': server.uuid}
nics_obj.objects.append(objects.ServerNic(
context, **nic_dict))
@ -614,7 +618,7 @@ class EngineManager(base_manager.BaseEngineManager):
raise exception.InterfaceAttachFailed(message=six.text_type(e))
LOG.info('Attaching interface successfully')
def _detach_interface(self, context, server, port_id):
def _detach_interface(self, context, server, port_id, preserve=False):
try:
self.driver.unplug_vif(context, server, port_id)
except exception.MoganException as e:
@ -624,7 +628,11 @@ class EngineManager(base_manager.BaseEngineManager):
raise exception.InterfaceDetachFailed(server_uuid=server.uuid)
else:
try:
self.network_api.delete_port(context, port_id, server.uuid)
if preserve:
vif_port = self.network_api.show_port(context, port_id)
self.network_api.unbind_port(context, vif_port)
else:
self.network_api.delete_port(context, port_id, server.uuid)
except Exception as e:
raise exception.InterfaceDetachFailed(server_uuid=server.uuid)
@ -637,7 +645,12 @@ class EngineManager(base_manager.BaseEngineManager):
def detach_interface(self, context, server, port_id):
LOG.debug("Detaching interface %(port_id) from server %(server)s",
{'port_id': port_id, 'server': server.uuid})
self._detach_interface(context, server, port_id)
try:
db_nic = objects.ServerNic.get_by_port_id(context, port_id)
preserve = db_nic['preserve_on_delete']
except exception.PortNotFound:
preserve = False
self._detach_interface(context, server, port_id, preserve)
LOG.info('Interface was successfully detached')

View File

@ -42,6 +42,7 @@ class ServerNic(base.MoganObject, object_base.VersionedObjectDictCompat):
'fixed_ips': object_fields.ListOfDictOfNullableStringsField(
nullable=True),
'floating_ip': object_fields.StringField(nullable=True),
'preserve_on_delete': object_fields.BooleanField(),
}
@staticmethod
@ -62,6 +63,10 @@ class ServerNic(base.MoganObject, object_base.VersionedObjectDictCompat):
def delete_by_port_id(cls, context, port_id):
cls.dbapi.server_nic_delete(context, port_id)
@classmethod
def get_by_port_id(cls, context, port_id):
return cls.dbapi.server_nic_get(context, port_id)
def save(self, context):
updates = self.obj_get_changes()
self.dbapi.server_nic_update_or_create(

View File

@ -37,6 +37,7 @@ def get_test_server(**kw):
}
],
'floating_ip': '',
'preserve_on_delete': False,
}, ]
return {

View File

@ -387,7 +387,7 @@ expected_object_fingerprints = {
'ServerFaultList': '1.0-43e8aad0258652921f929934e9e048fd',
'Flavor': '1.0-9f7166aa387d89ec40cd699019d0c9a9',
'MyObj': '1.1-aad62eedc5a5cc8bcaf2982c285e753f',
'ServerNic': '1.0-0494306157ef437802260ff8b51cf5cf',
'ServerNic': '1.0-fb405af29a68a9a60a495962a11579cc',
'ServerNics': '1.0-33a2e1bb91ad4082f9f63429b77c1244',
'Quota': '1.0-c8caa082f4d726cb63fdc5943f7cd186',
'KeyPair': '1.0-1a1ea1f9b4d03503f5c13b52d1432fa9',