Merge "Add/Remove/Modify vNIC post deployment Edit"
This commit is contained in:
commit
29047a3d2e
@ -8,6 +8,8 @@ from powervc.common.gettextutils import _
|
||||
from powervc.neutron.common import utils
|
||||
from powervc.neutron.db import powervc_db_v2
|
||||
|
||||
import time
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -105,3 +107,21 @@ class PVCRpcCallbacks(object):
|
||||
pvc_ins_uuid)
|
||||
LOG.info(_("- local_ids: %s"), local_ids)
|
||||
return local_ids
|
||||
|
||||
def set_pvc_id_to_port(self, context, local_port_id, pvc_port_id):
|
||||
LOG.info(_("Neutron Agent RPC: start set pvc id to port:"))
|
||||
# Sometimes for db session data delay, repeat 3 times to get the
|
||||
# latest port info from local neutron db.
|
||||
local_port = None
|
||||
fetchTimes = 0
|
||||
while True:
|
||||
local_port = self.db.get_port(local_id=local_port_id)
|
||||
# Delay 3 times, each 10 sec to fetch the local port db obj
|
||||
if local_port or fetchTimes >= 2:
|
||||
break
|
||||
fetchTimes += 1
|
||||
LOG.info(_("Cannot get port from local temporarily, wait 10sec.."))
|
||||
time.sleep(10)
|
||||
|
||||
self.db.set_port_pvc_id(local_port, pvc_port_id)
|
||||
LOG.info(_("End of set powervc uuid to port."))
|
||||
|
@ -443,13 +443,63 @@ class PowerVCDriver(driver.ComputeDriver):
|
||||
"""List the volumes attached to the specified instance."""
|
||||
return self._service.list_os_attachments(server_id)
|
||||
|
||||
def attach_interface(self, instance, image_meta, network_info):
|
||||
"""Attach an interface to the instance."""
|
||||
raise NotImplementedError()
|
||||
def attach_interface(self, instance, image_meta, vif):
|
||||
"""Attach an interface to the instance.
|
||||
"""
|
||||
context = nova.context.get_admin_context()
|
||||
try:
|
||||
server_id = instance.get('uuid')
|
||||
LOG.debug(_("Local Server uuid: %s") % server_id)
|
||||
|
||||
def detach_interface(self, instance, network_info):
|
||||
"""Detach an interface from the instance."""
|
||||
raise NotImplementedError()
|
||||
port_id, network_id, ipAddress = self.\
|
||||
_get_port_network_ipaddress_from_vif(vif)
|
||||
except Exception as e:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error(_("attach interface failed with wrong paras: %s"),
|
||||
e, instance=instance)
|
||||
|
||||
# call service to attach interface
|
||||
self._service.attach_interface(context,
|
||||
instance,
|
||||
port_id,
|
||||
network_id,
|
||||
ipAddress)
|
||||
|
||||
def _get_port_network_ipaddress_from_vif(self, vif):
|
||||
"""Get port uuid, network uuid, and ip Address from vif
|
||||
"""
|
||||
local_port_id = ''
|
||||
local_network_id = ''
|
||||
ipAddress = ''
|
||||
|
||||
local_port_id = vif.get('id')
|
||||
local_network = vif.get('network')
|
||||
if local_network:
|
||||
local_network_id = local_network.get('id')
|
||||
local_subnet = local_network.get('subnets')
|
||||
if local_subnet and local_subnet[0]:
|
||||
ipAddresses = local_subnet[0].get('ips')
|
||||
if ipAddresses and ipAddresses[0]:
|
||||
ipAddress = ipAddresses[0].get('address')
|
||||
|
||||
LOG.debug(_("Local port uuid: %s") % local_port_id)
|
||||
LOG.debug(_("Local network uuid: %s") % local_network_id)
|
||||
LOG.debug(_("ip address: %s") % ipAddress)
|
||||
return (local_port_id, local_network_id, ipAddress)
|
||||
|
||||
def detach_interface(self, instance, vif):
|
||||
"""Detach an interface from the instance.
|
||||
"""
|
||||
context = nova.context.get_admin_context()
|
||||
local_port_id = vif.get('id')
|
||||
LOG.debug(_("Local port uuid: %s") % local_port_id)
|
||||
if not local_port_id:
|
||||
LOG.error(_("no port id found to detach the interface."))
|
||||
return
|
||||
# call service to detach interface
|
||||
self._service.detach_interface(context,
|
||||
instance,
|
||||
local_port_id)
|
||||
|
||||
def migrate_disk_and_power_off(self, context, instance, dest,
|
||||
instance_type, network_info,
|
||||
|
@ -69,3 +69,13 @@ class NetworkAPI(object):
|
||||
method_name = "set_device_id_on_port_by_pvc_instance_uuid"
|
||||
result = self.rpcclient.call(ctxt, method_name, **kwargs)
|
||||
return result
|
||||
|
||||
def set_pvc_id_to_port(self, ctxt, local_port_id, pvc_port_id):
|
||||
"""Set the pvc_port_id to local db port by local_port_id
|
||||
"""
|
||||
kwargs = {}
|
||||
kwargs['local_port_id'] = local_port_id
|
||||
kwargs['pvc_port_id'] = pvc_port_id
|
||||
method_name = "set_pvc_id_to_port"
|
||||
result = self.rpcclient.call(ctxt, method_name, **kwargs)
|
||||
return result
|
||||
|
@ -1329,3 +1329,65 @@ class PowerVCService(object):
|
||||
if pvc_volume_id is not None and local_volume_id != '':
|
||||
cache_volume[pvc_volume_id] = local_volume_id
|
||||
return cache_volume
|
||||
|
||||
def attach_interface(self, context, instance, local_port_id,
|
||||
local_network_id, ipAddress):
|
||||
"""attach a new port to a specified vm
|
||||
:param context: context for this action
|
||||
:param instance: the vm instance that new interface attach to
|
||||
:param local_port_id: the local port uuid
|
||||
:param local_network_id: the powervc network uuid
|
||||
:param ipAddress: the ipv4 address that set to the vm
|
||||
"""
|
||||
pvc_port_id = self.get_pvc_port_uuid(context, local_port_id)
|
||||
# get client server instance from a db instance
|
||||
server_with_pvc_id = self._get_server(instance)
|
||||
# get the powervc client server instance from novaclient
|
||||
server_client_obj = self._manager.get(server_with_pvc_id)
|
||||
# PowerVC restAPI will thrown BadRequest exception if set port_id
|
||||
# and net-id/ipaddress in the same time.
|
||||
# So if there is powervc port id matches to local port id existed, set
|
||||
# the net_id and ipaddress to ''.
|
||||
# If there is no port in powervc matches to local port existed, get
|
||||
# and call restAPI with net-id and ipAddress.
|
||||
if pvc_port_id:
|
||||
pvc_network_id = ''
|
||||
ipAddress = ''
|
||||
else:
|
||||
# the 'net-id' will be changed to the 'uuid' in the boot method
|
||||
pvc_network_id = self.get_pvc_network_uuid(context,
|
||||
local_network_id)
|
||||
LOG.debug(_("PowerVC nic uuid: %s") % pvc_network_id)
|
||||
# get the raw_response data from patched novaclient interface attach
|
||||
# function. For detail, see the extensions/nova.py#interface_attach()
|
||||
server_client_obj.interface_attach(pvc_port_id, pvc_network_id,
|
||||
ipAddress)
|
||||
# Call Neutron RPC to update the pvc id to port obj immediately.
|
||||
# self.set_pvc_id_to_port(context, local_port_id, pvc_port_id)
|
||||
|
||||
# TODO Loop to get the pvc_id from local db. Return this method until
|
||||
# pvc_id got verified in local db, Default timeout is 150s
|
||||
|
||||
def detach_interface(self, context, instance, local_port_id):
|
||||
"""detach a port from a specified vm
|
||||
:param context: context for this action
|
||||
:param instance: the vm instance that new interface attach to
|
||||
:param local_port_id: the local port uuid
|
||||
"""
|
||||
pvc_port_uuid = self._api.get_pvc_port_uuid(context, local_port_id)
|
||||
LOG.debug(_("pvc_port_uuid to be detach: %s"), pvc_port_uuid)
|
||||
# get client server instance from a db instance
|
||||
server_with_pvc_id = self._get_server(instance)
|
||||
# get the powervc client server instance from novaclient
|
||||
server_client_obj = self._manager.get(server_with_pvc_id)
|
||||
response = server_client_obj.interface_detach(pvc_port_uuid)
|
||||
LOG.debug(_("detach response: %s"), response)
|
||||
return response
|
||||
|
||||
def set_pvc_id_to_port(self, ctx, local_port_id, pvc_port_id):
|
||||
"""
|
||||
After attach an interface to a server, update the neutorn ports
|
||||
to reflect latest ports information to neutron db.
|
||||
"""
|
||||
pvc_id = self._api.set_pvc_id_to_port(ctx, local_port_id, pvc_port_id)
|
||||
return pvc_id
|
||||
|
Loading…
Reference in New Issue
Block a user