def test_brick_get_connector(self): root_helper = utils.get_root_helper() self.mox.StubOutClassWithMocks(connector, "ISCSIConnector") connector.ISCSIConnector( execute=putils.execute, driver=None, root_helper=root_helper, use_multipath=False, device_scan_attempts=3 ) self.mox.StubOutClassWithMocks(connector, "FibreChannelConnector") connector.FibreChannelConnector( execute=putils.execute, driver=None, root_helper=root_helper, use_multipath=False, device_scan_attempts=3 ) self.mox.StubOutClassWithMocks(connector, "AoEConnector") connector.AoEConnector(execute=putils.execute, driver=None, root_helper=root_helper, device_scan_attempts=3) self.mox.StubOutClassWithMocks(connector, "LocalConnector") connector.LocalConnector(execute=putils.execute, driver=None, root_helper=root_helper, device_scan_attempts=3) self.mox.ReplayAll() utils.brick_get_connector("iscsi") utils.brick_get_connector("fibre_channel") utils.brick_get_connector("aoe") utils.brick_get_connector("local") self.mox.VerifyAll()
def test_brick_get_connector(self): root_helper = utils.get_root_helper() self.mox.StubOutClassWithMocks(connector, 'ISCSIConnector') connector.ISCSIConnector(execute=putils.execute, driver=None, root_helper=root_helper, use_multipath=False) self.mox.StubOutClassWithMocks(connector, 'FibreChannelConnector') connector.FibreChannelConnector(execute=putils.execute, driver=None, root_helper=root_helper, use_multipath=False) self.mox.StubOutClassWithMocks(connector, 'AoEConnector') connector.AoEConnector(execute=putils.execute, driver=None, root_helper=root_helper) self.mox.StubOutClassWithMocks(connector, 'LocalConnector') connector.LocalConnector(execute=putils.execute, driver=None, root_helper=root_helper) self.mox.ReplayAll() utils.brick_get_connector('iscsi') utils.brick_get_connector('fibre_channel') utils.brick_get_connector('aoe') utils.brick_get_connector('local') self.mox.VerifyAll()
def setUp(self): super(CoraidDriverImageTestCases, self).setUp() self.fake_dev_path = '/dev/ether/fake_dev' self.fake_connection = {'driver_volume_type': 'aoe', 'data': {'target_shelf': fake_shelf, 'target_lun': fake_lun}} self.fake_volume_info = { 'shelf': self.fake_connection['data']['target_shelf'], 'lun': self.fake_connection['data']['target_lun']} self.mox.StubOutWithMock(self.driver, 'initialize_connection') self.driver.initialize_connection(fake_volume, {})\ .AndReturn(self.fake_connection) self.mox.StubOutWithMock(self.driver, 'terminate_connection') self.driver.terminate_connection(fake_volume, mox.IgnoreArg(), force=False).AndReturn(None) root_helper = 'sudo cinder-rootwrap /etc/cinder/rootwrap.conf' self.mox.StubOutWithMock(connector, 'get_connector_properties') connector.get_connector_properties(root_helper, CONF.my_ip).\ AndReturn({}) self.mox.StubOutWithMock(utils, 'brick_get_connector') aoe_initiator = self.mox.CreateMockAnything() utils.brick_get_connector('aoe', device_scan_attempts=3, use_multipath=False, conn=mox.IgnoreArg()).\ AndReturn(aoe_initiator) aoe_initiator\ .connect_volume(self.fake_connection['data'])\ .AndReturn({'path': self.fake_dev_path}) aoe_initiator.check_valid_device(self.fake_dev_path)\ .AndReturn(True) aoe_initiator.disconnect_volume( {'target_shelf': self.fake_volume_info['shelf'], 'target_lun': self.fake_volume_info['lun']}, mox.IgnoreArg())
def _attach_volume(self, context, volume, properties, remote=False): """Attach the volume.""" if remote: rpcapi = volume_rpcapi.VolumeAPI() conn = rpcapi.initialize_connection(context, volume, properties) else: conn = self.initialize_connection(volume, properties) # Use Brick's code to do attach/detach use_multipath = self.configuration.use_multipath_for_image_xfer device_scan_attempts = self.configuration.num_volume_device_scan_tries protocol = conn['driver_volume_type'] connector = utils.brick_get_connector(protocol, use_multipath=use_multipath, device_scan_attempts= device_scan_attempts, conn=conn) device = connector.connect_volume(conn['data']) host_device = device['path'] if not connector.check_valid_device(host_device): raise exception.DeviceUnavailable(path=host_device, reason=(_("Unable to access " "the backend storage " "via the path " "%(path)s.") % {'path': host_device})) return {'conn': conn, 'device': device, 'connector': connector}
def test_brick_get_connector(self, mock_helper, mock_factory): output = utils.brick_get_connector('protocol') mock_helper.assert_called_once_with() self.assertEqual(mock_factory.return_value, output) mock_factory.assert_called_once_with( 'protocol', mock_helper.return_value, driver=None, execute=putils.execute, use_multipath=False, device_scan_attempts=3)
def _attach_volume(self, context, volume, properties, remote=False): """Attach the volume.""" if remote: # Call remote manager's initialize_connection which includes # driver's create_export and initialize_connection rpcapi = volume_rpcapi.VolumeAPI() conn = rpcapi.initialize_connection(context, volume, properties) else: # Call local driver's create_export and initialize_connection. # NOTE(avishay) This is copied from the manager's code - need to # clean this up in the future. model_update = None try: LOG.debug(("Volume %s: creating export"), volume["id"]) model_update = self.create_export(context, volume) if model_update: volume = self.db.volume_update(context, volume["id"], model_update) except exception.CinderException as ex: if model_update: LOG.exception( _("Failed updating model of volume " "%(volume_id)s with driver provided model " "%(model)s") % {"volume_id": volume["id"], "model": model_update} ) raise exception.ExportFailure(reason=ex) try: conn = self.initialize_connection(volume, properties) except Exception as err: try: err_msg = _("Unable to fetch connection information from " "backend: %(err)s") % {"err": err} LOG.error(err_msg) LOG.debug("Cleaning up failed connect initialization.") self.remove_export(context, volume) except Exception as ex: ex_msg = _("Error encountered during cleanup " "of a failed attach: %(ex)s") % {"ex": ex} LOG.error(err_msg) raise exception.VolumeBackendAPIException(data=ex_msg) raise exception.VolumeBackendAPIException(data=err_msg) # Use Brick's code to do attach/detach use_multipath = self.configuration.use_multipath_for_image_xfer device_scan_attempts = self.configuration.num_volume_device_scan_tries protocol = conn["driver_volume_type"] connector = utils.brick_get_connector( protocol, use_multipath=use_multipath, device_scan_attempts=device_scan_attempts, conn=conn ) device = connector.connect_volume(conn["data"]) host_device = device["path"] if not connector.check_valid_device(host_device): raise exception.DeviceUnavailable( path=host_device, reason=( _("Unable to access " "the backend storage " "via the path " "%(path)s.") % {"path": host_device} ), ) return {"conn": conn, "device": device, "connector": connector}
def setUp(self): super(CoraidDriverImageTestCases, self).setUp() self.fake_dev_path = "/dev/ether/fake_dev" self.fake_connection = { "driver_volume_type": "aoe", "data": {"target_shelf": fake_shelf, "target_lun": fake_lun}, } self.fake_volume_info = { "shelf": self.fake_connection["data"]["target_shelf"], "lun": self.fake_connection["data"]["target_lun"], } self.mox.StubOutWithMock(self.driver, "initialize_connection") self.driver.initialize_connection(fake_volume, {}).AndReturn(self.fake_connection) self.mox.StubOutWithMock(self.driver, "terminate_connection") self.driver.terminate_connection(fake_volume, mox.IgnoreArg(), force=False).AndReturn(None) root_helper = "sudo cinder-rootwrap /etc/cinder/rootwrap.conf" self.mox.StubOutWithMock(connector, "get_connector_properties") connector.get_connector_properties(root_helper, CONF.my_ip).AndReturn({}) self.mox.StubOutWithMock(utils, "brick_get_connector") aoe_initiator = self.mox.CreateMockAnything() utils.brick_get_connector("aoe", device_scan_attempts=3, use_multipath=False, conn=mox.IgnoreArg()).AndReturn( aoe_initiator ) aoe_initiator.connect_volume(self.fake_connection["data"]).AndReturn({"path": self.fake_dev_path}) aoe_initiator.check_valid_device(self.fake_dev_path).AndReturn(True) aoe_initiator.disconnect_volume( {"target_shelf": self.fake_volume_info["shelf"], "target_lun": self.fake_volume_info["lun"]}, mox.IgnoreArg(), )
def _connect_device(self, conn): """Establish connection to device.""" use_multipath = CONF.use_multipath_for_image_xfer device_scan_attempts = CONF.num_volume_device_scan_tries protocol = conn["driver_volume_type"] connector = utils.brick_get_connector( protocol, use_multipath=use_multipath, device_scan_attempts=device_scan_attempts, conn=conn ) vol_handle = connector.connect_volume(conn["data"]) return {"conn": conn, "device": vol_handle, "connector": connector}
def _is_volume_attached(self, volume_id): if not volume_id: return False conn = {"driver_volume_type": "HUAWEISDSHYPERVISOR", "data": {"volume_id": "volume-" + volume_id}} use_multipath = self.configuration.use_multipath_for_image_xfer device_scan_attempts = self.configuration.num_volume_device_scan_tries protocol = conn["driver_volume_type"] connector = utils.brick_get_connector( protocol, use_multipath=use_multipath, device_scan_attempts=device_scan_attempts, conn=conn ) is_volume_attached = connector.is_volume_connected(conn["data"]["volume_id"]) return is_volume_attached
def _connect_device(self, conn): """Establish connection to device.""" use_multipath = CONF.use_multipath_for_image_xfer device_scan_attempts = CONF.num_volume_device_scan_tries protocol = conn['driver_volume_type'] connector = utils.brick_get_connector( protocol, use_multipath=use_multipath, device_scan_attempts=device_scan_attempts, conn=conn) vol_handle = connector.connect_volume(conn['data']) return {'conn': conn, 'device': vol_handle, 'connector': connector}
def _connect_target(self, container): connector = None try: sis, iqn, portal = self._get_sis_iqn_portal(container) conn = {'driver_volume_type': 'iscsi', 'data': { 'target_discovered': False, 'target_iqn': iqn, 'target_portal': portal, 'target_lun': 0, 'volume_id': None, 'discard': False}} connector = utils.brick_get_connector( conn['driver_volume_type'], use_multipath=False, device_scan_attempts=10, conn=conn) # Setup ACL initiator = connector.get_initiator() self._register_acl(container, initiator, sis) # Attach Target attach_info = {} attach_info['target_portal'] = portal attach_info['target_iqn'] = iqn attach_info['target_lun'] = 0 retries = 10 while True: try: attach_info.update( connector.connect_volume(conn['data'])) break except brick_exception.FailedISCSITargetPortalLogin: retries -= 1 if not retries: LOG.error("Could not log into portal before end of " "polling period") raise LOG.debug("Failed to login to portal, retrying") eventlet.sleep(2) device_path = attach_info['path'] yield device_path finally: # Close target connection if connector: # Best effort disconnection try: connector.disconnect_volume(attach_info, attach_info) except Exception: pass
def _attch(self, conn): """ Creates the properties dict required by the brick utils to attache the volume. :param conn: connection information retrived from SL/iSCSI tools. """ protocol = conn["driver_volume_type"] LOG.debug("Attaching for protocol '%s'" % protocol) connector = utils.brick_get_connector(protocol) device = connector.connect_volume(conn["data"]) host_device = device["path"] if not connector.check_valid_device(host_device): raise exception.InvalidResults("Unable to get valid device %s" % host_device) return {"conn": conn, "device": device, "connector": connector}
def _is_volume_attached(self, volume_id): if not volume_id: return False conn = {'driver_volume_type': 'HUAWEISDSHYPERVISOR', 'data': {'volume_id': 'volume-' + volume_id}} use_multipath = self.configuration.use_multipath_for_image_xfer device_scan_attempts = self.configuration.num_volume_device_scan_tries protocol = conn['driver_volume_type'] connector = utils.brick_get_connector(protocol, use_multipath=use_multipath, device_scan_attempts= device_scan_attempts, conn=conn) is_volume_attached = connector.is_volume_connected( conn['data']['volume_id']) return is_volume_attached
def _remove_device(self, properties, device): LOG.debug("enter: _remove_device") if not properties or not device: LOG.warning(_LW("_remove_device: invalid properties or device.")) return use_multipath = self.configuration.use_multipath_for_image_xfer device_scan_attempts = self.configuration.num_volume_device_scan_tries protocol = properties["driver_volume_type"] connector = utils.brick_get_connector( protocol, use_multipath=use_multipath, device_scan_attempts=device_scan_attempts, conn=properties ) connector.disconnect_volume(properties["data"], device) LOG.debug("leave: _remove_device")
def _scan_device(self, properties): LOG.debug("enter: _scan_device") use_multipath = self.configuration.use_multipath_for_image_xfer device_scan_attempts = self.configuration.num_volume_device_scan_tries protocol = properties["driver_volume_type"] connector = utils.brick_get_connector( protocol, use_multipath=use_multipath, device_scan_attempts=device_scan_attempts, conn=properties ) device = connector.connect_volume(properties["data"]) host_device = device["path"] if not connector.check_valid_device(host_device): msg = _("Unable to access the backend storage " "via the path %(path)s.") % {"path": host_device} raise exception.VolumeBackendAPIException(data=msg) LOG.debug("leave: _scan_device") return device
def _remove_device(self, properties, device): LOG.debug('enter: _remove_device') if not properties or not device: LOG.warning('_remove_device: invalid properties or device.') return use_multipath = self.configuration.use_multipath_for_image_xfer device_scan_attempts = self.configuration.num_volume_device_scan_tries protocol = properties['driver_volume_type'] connector = utils.brick_get_connector( protocol, use_multipath=use_multipath, device_scan_attempts=device_scan_attempts, conn=properties) connector.disconnect_volume(properties['data'], device) LOG.debug('leave: _remove_device')
def _attach_context(self, connection): use_multipath = self.configuration.use_multipath_for_image_xfer device_scan_attempts = self.configuration.num_volume_device_scan_tries protocol = connection['driver_volume_type'] connector = utils.brick_get_connector( protocol, use_multipath=use_multipath, device_scan_attempts=device_scan_attempts, conn=connection) attach_info = None try: attach_info = self._connect_device(connection) yield attach_info except exception.DeviceUnavailable as exc: attach_info = exc.kwargs.get('attach_info', None) raise finally: if attach_info: connector.disconnect_volume(attach_info['conn']['data'], attach_info['device'])
def _is_volume_attached(self, volume_id): if not volume_id: return False conn = { 'driver_volume_type': 'HUAWEISDSHYPERVISOR', 'data': { 'volume_id': 'volume-' + volume_id } } use_multipath = self.configuration.use_multipath_for_image_xfer device_scan_attempts = self.configuration.num_volume_device_scan_tries protocol = conn['driver_volume_type'] connector = utils.brick_get_connector( protocol, use_multipath=use_multipath, device_scan_attempts=device_scan_attempts, conn=conn) is_volume_attached = connector.is_volume_connected( conn['data']['volume_id']) return is_volume_attached
def _scan_device(self, properties): LOG.debug('enter: _scan_device') use_multipath = self.configuration.use_multipath_for_image_xfer device_scan_attempts = self.configuration.num_volume_device_scan_tries protocol = properties['driver_volume_type'] connector = utils.brick_get_connector(protocol, use_multipath=use_multipath, device_scan_attempts= device_scan_attempts, conn=properties) device = connector.connect_volume(properties['data']) host_device = device['path'] if not connector.check_valid_device(host_device): msg = (_('Unable to access the backend storage ' 'via the path %(path)s.') % {'path': host_device}) raise exception.VolumeBackendAPIException(data=msg) LOG.debug('leave: _scan_device') return device
def _attach_ldev(self, ldev, properties): volume = { 'provider_location': six.text_type(ldev), } conn = self.initialize_connection(volume, properties) try: connector = cinder_utils.brick_get_connector( conn['driver_volume_type'], use_multipath=self.conf.use_multipath_for_image_xfer, device_scan_attempts=self.conf.num_volume_device_scan_tries, conn=conn) device = connector.connect_volume(conn['data']) except Exception as ex: with excutils.save_and_reraise_exception(): utils.output_log(634, ldev=ldev, reason=six.text_type(ex)) self._terminate_connection(volume, properties) return { 'conn': conn, 'device': device, 'connector': connector, }
def _connect_device(self, conn): # Use Brick's code to do attach/detach use_multipath = self.configuration.use_multipath_for_image_xfer device_scan_attempts = self.configuration.num_volume_device_scan_tries protocol = conn['driver_volume_type'] connector = utils.brick_get_connector( protocol, use_multipath=use_multipath, device_scan_attempts=device_scan_attempts, conn=conn) device = connector.connect_volume(conn['data']) attach_info = {'conn': conn, 'device': device['path'], 'connector': connector} if conn['data']['encrypted']: symlink_dev = '/dev/rbd-volume-%s' % conn['data']['volume_id'] utils.execute('ln', '--symbolic', '--force', device['path'], symlink_dev, run_as_root=True) attach_info = {'conn': conn, 'device': {'path': symlink_dev}, 'connector': connector} if not conn['data']['encrypted']: host_device = device['path'] unavailable = True try: # Secure network file systems will NOT run as root. root_access = not self.secure_file_operations_enabled() unavailable = not connector.check_valid_device(host_device, root_access) except Exception: LOG.exception(_LE('Could not validate device %s'), host_device) if unavailable and conn['encrypted']: raise exception.DeviceUnavailable(path=host_device, attach_info=attach_info, reason=(_("Unable to access " "the backend storage " "via the path " "%(path)s.") % {'path': host_device})) return attach_info
def _connect_vol(self, context, vol): connector = None try: # Start connection, get the connector object and create the # export (ACL, IP-Pools, etc) conn = self._initialize_connection_2_2( vol, {'multipath': False}) connector = utils.brick_get_connector( conn['driver_volume_type'], use_multipath=False, device_scan_attempts=10, conn=conn) connector_info = {'initiator': connector.get_initiator()} self._create_export_2_2(None, vol, connector_info) retries = 10 attach_info = conn['data'] while True: try: attach_info.update( connector.connect_volume(conn['data'])) break except brick_exception.FailedISCSITargetPortalLogin: retries -= 1 if not retries: LOG.error("Could not log into portal before end of " "polling period") raise LOG.debug("Failed to login to portal, retrying") eventlet.sleep(2) device_path = attach_info['path'] yield device_path finally: # Close target connection if connector: # Best effort disconnection try: connector.disconnect_volume(attach_info, attach_info) except Exception: pass
def test_brick_get_connector(self): root_helper = utils.get_root_helper() self.mox.StubOutClassWithMocks(connector, 'ISCSIConnector') connector.ISCSIConnector(execute=putils.execute, driver=None, root_helper=root_helper, use_multipath=False, device_scan_attempts=3) self.mox.StubOutClassWithMocks(connector, 'FibreChannelConnector') connector.FibreChannelConnector(execute=putils.execute, driver=None, root_helper=root_helper, use_multipath=False, device_scan_attempts=3) self.mox.StubOutClassWithMocks(connector, 'AoEConnector') connector.AoEConnector(execute=putils.execute, driver=None, root_helper=root_helper, device_scan_attempts=3) self.mox.StubOutClassWithMocks(connector, 'LocalConnector') connector.LocalConnector(execute=putils.execute, driver=None, root_helper=root_helper, device_scan_attempts=3) self.mox.ReplayAll() utils.brick_get_connector('iscsi') utils.brick_get_connector('fibre_channel') utils.brick_get_connector('aoe') utils.brick_get_connector('local') self.mox.VerifyAll()
def _attach_ldev(self, ldev, properties): """Attach the specified LDEV to the server.""" volume = { 'provider_location': six.text_type(ldev), } conn = self.initialize_connection(volume, properties) try: connector = cinder_utils.brick_get_connector( conn['driver_volume_type'], use_multipath=self.conf.use_multipath_for_image_xfer, device_scan_attempts=self.conf.num_volume_device_scan_tries, conn=conn) device = connector.connect_volume(conn['data']) except Exception as ex: with excutils.save_and_reraise_exception(): utils.output_log(MSG.CONNECT_VOLUME_FAILED, ldev=ldev, reason=six.text_type(ex)) self._terminate_connection(volume, properties) return { 'conn': conn, 'device': device, 'connector': connector, }
def _attach_volume(self, context, volume, properties, remote=False): """Attach the volume.""" if remote: rpcapi = volume_rpcapi.VolumeAPI() conn = rpcapi.initialize_connection(context, volume, properties) else: conn = self.initialize_connection(volume, properties) # Use Brick's code to do attach/detach use_multipath = self.configuration.use_multipath_for_image_xfer protocol = conn['driver_volume_type'] connector = utils.brick_get_connector(protocol, use_multipath=use_multipath) device = connector.connect_volume(conn['data']) host_device = device['path'] if not connector.check_valid_device(host_device): raise exception.DeviceUnavailable(path=host_device, reason=(_("Unable to access " "the backend storage " "via the path " "%(path)s.") % {'path': host_device})) return {'conn': conn, 'device': device, 'connector': connector}
def _attach_volume(self, context, volume, properties, remote=False): """Attach the volume.""" if remote: # Call remote manager's initialize_connection which includes # driver's create_export and initialize_connection rpcapi = volume_rpcapi.VolumeAPI() conn = rpcapi.initialize_connection(context, volume, properties) else: # Call local driver's create_export and initialize_connection. # NOTE(avishay) This is copied from the manager's code - need to # clean this up in the future. model_update = None try: LOG.debug(_("Volume %s: creating export"), volume['id']) model_update = self.create_export(context, volume) if model_update: volume = self.db.volume_update(context, volume['id'], model_update) except exception.CinderException as ex: if model_update: LOG.exception( _("Failed updating model of volume " "%(volume_id)s with driver provided model " "%(model)s") % { 'volume_id': volume['id'], 'model': model_update }) raise exception.ExportFailure(reason=ex) try: conn = self.initialize_connection(volume, properties) except Exception as err: try: err_msg = (_('Unable to fetch connection information from ' 'backend: %(err)s') % { 'err': err }) LOG.error(err_msg) LOG.debug("Cleaning up failed connect initialization.") self.remove_export(context, volume) except Exception as ex: ex_msg = (_('Error encountered during cleanup ' 'of a failed attach: %(ex)s') % { 'ex': ex }) LOG.error(err_msg) raise exception.VolumeBackendAPIException(data=ex_msg) raise exception.VolumeBackendAPIException(data=err_msg) # Use Brick's code to do attach/detach use_multipath = self.configuration.use_multipath_for_image_xfer device_scan_attempts = self.configuration.num_volume_device_scan_tries protocol = conn['driver_volume_type'] connector = utils.brick_get_connector( protocol, use_multipath=use_multipath, device_scan_attempts=device_scan_attempts, conn=conn) device = connector.connect_volume(conn['data']) host_device = device['path'] if not connector.check_valid_device(host_device): raise exception.DeviceUnavailable(path=host_device, reason=(_("Unable to access " "the backend storage " "via the path " "%(path)s.") % { 'path': host_device })) return {'conn': conn, 'device': device, 'connector': connector}