def _test_volume_attach(self, driver_bdm, bdm_dict, fake_volume, check_attach=True, fail_check_attach=False, driver_attach=False, fail_driver_attach=False, access_mode='rw'): elevated_context = self.context.elevated() self.stubs.Set(self.context, 'elevated', lambda: elevated_context) self.mox.StubOutWithMock(driver_bdm._bdm_obj, 'save') self.mox.StubOutWithMock(encryptors, 'get_encryption_metadata') instance = {'id': 'fake_id', 'uuid': 'fake_uuid'} connector = {'ip': 'fake_ip', 'host': 'fake_host'} connection_info = {'data': {'access_mode': access_mode}} expected_conn_info = {'data': {'access_mode': access_mode}, 'serial': fake_volume['id']} enc_data = {'fake': 'enc_data'} self.volume_api.get(self.context, fake_volume['id']).AndReturn(fake_volume) if check_attach: if not fail_check_attach: self.volume_api.check_attach(self.context, fake_volume, instance=instance).AndReturn(None) else: self.volume_api.check_attach(self.context, fake_volume, instance=instance).AndRaise( test.TestingException) return instance, expected_conn_info self.virt_driver.get_volume_connector(instance).AndReturn(connector) self.volume_api.initialize_connection( elevated_context, fake_volume['id'], connector).AndReturn(connection_info) if driver_attach: encryptors.get_encryption_metadata( elevated_context, self.volume_api, fake_volume['id'], connection_info).AndReturn(enc_data) if not fail_driver_attach: self.virt_driver.attach_volume( elevated_context, expected_conn_info, instance, bdm_dict['device_name'], disk_bus=bdm_dict['disk_bus'], device_type=bdm_dict['device_type'], encryption=enc_data).AndReturn(None) else: self.virt_driver.attach_volume( elevated_context, expected_conn_info, instance, bdm_dict['device_name'], disk_bus=bdm_dict['disk_bus'], device_type=bdm_dict['device_type'], encryption=enc_data).AndRaise(test.TestingException) self.volume_api.terminate_connection( elevated_context, fake_volume['id'], expected_conn_info).AndReturn(None) return instance, expected_conn_info self.volume_api.attach(elevated_context, fake_volume['id'], 'fake_uuid', bdm_dict['device_name'], mode=access_mode).AndReturn(None) driver_bdm._bdm_obj.save(self.context).AndReturn(None) return instance, expected_conn_info
def driver_detach(self, context, instance, volume_api, virt_driver): connection_info = self['connection_info'] mp = self['mount_device'] volume_id = self.volume_id LOG.info(_LI('Attempting to driver detach volume %(volume_id)s from ' ' mountpoint %(mp)s'), {'volume_id': volume_id, 'mp': mp}, instance=instance) try: if not virt_driver.instance_exists(instance): LOG.warning(_LW('Detaching volume from unknown instance'), instance=instance) encryption = encryptors.get_encryption_metadata(context, volume_api, volume_id, connection_info) virt_driver.detach_volume(connection_info, instance, mp, encryption=encryption) except exception.DiskNotFound as err: LOG.warning(_LW('Ignoring DiskNotFound exception while ' 'detaching volume %(volume_id)s from ' '%(mp)s : %(err)s'), {'volume_id': volume_id, 'mp': mp, 'err': err}, instance=instance) except Exception: with excutils.save_and_reraise_exception(): LOG.exception(_LE('Failed to detach volume ' '%(volume_id)s from %(mp)s'), {'volume_id': volume_id, 'mp': mp}, instance=instance) volume_api.roll_detaching(context, volume_id)
def attach(self, context, instance, volume_api, virt_driver, do_check_attach=True, do_driver_attach=False): volume = volume_api.get(context, self.volume_id) if do_check_attach: volume_api.check_attach(context, volume, instance=instance) volume_id = volume['id'] context = context.elevated() connector = virt_driver.get_volume_connector(instance) connection_info = volume_api.initialize_connection( context, volume_id, connector) if 'serial' not in connection_info: connection_info['serial'] = self.volume_id self._preserve_multipath_id(connection_info) # If do_driver_attach is False, we will attach a volume to an instance # at boot time. So actual attach is done by instance creation code. if do_driver_attach: encryption = encryptors.get_encryption_metadata( context, volume_api, volume_id, connection_info) try: virt_driver.attach_volume(context, connection_info, instance, self['mount_device'], disk_bus=self['disk_bus'], device_type=self['device_type'], encryption=encryption) except Exception: # pylint: disable=W0702 with excutils.save_and_reraise_exception(): LOG.exception(_("Driver failed to attach volume " "%(volume_id)s at %(mountpoint)s"), { 'volume_id': volume_id, 'mountpoint': self['mount_device'] }, context=context, instance=instance) volume_api.terminate_connection(context, volume_id, connector) self['connection_info'] = connection_info mode = 'rw' if 'data' in connection_info: mode = connection_info['data'].get('access_mode', 'rw') if volume['attach_status'] == "detached": volume_api.attach(context, volume_id, instance['uuid'], self['mount_device'], mode=mode)
def attach( self, context, instance, volume_api, virt_driver, do_check_attach=True, do_driver_attach=False, **kwargs ): volume = volume_api.get(context, self.volume_id) if do_check_attach: volume_api.check_attach(context, volume, instance=instance) volume_id = volume["id"] context = context.elevated() connector = virt_driver.get_volume_connector(instance) connection_info = volume_api.initialize_connection(context, volume_id, connector) if "serial" not in connection_info: connection_info["serial"] = self.volume_id self._preserve_multipath_id(connection_info) # If do_driver_attach is False, we will attach a volume to an instance # at boot time. So actual attach is done by instance creation code. if do_driver_attach: encryption = encryptors.get_encryption_metadata(context, volume_api, volume_id, connection_info) try: virt_driver.attach_volume( context, connection_info, instance, self["mount_device"], disk_bus=self["disk_bus"], device_type=self["device_type"], encryption=encryption, ) except Exception: with excutils.save_and_reraise_exception(): LOG.exception( _LE("Driver failed to attach volume " "%(volume_id)s at %(mountpoint)s"), {"volume_id": volume_id, "mountpoint": self["mount_device"]}, context=context, instance=instance, ) volume_api.terminate_connection(context, volume_id, connector) self["connection_info"] = connection_info if self.volume_size is None: self.volume_size = volume.get("size") mode = "rw" if "data" in connection_info: mode = connection_info["data"].get("access_mode", "rw") if volume["attach_status"] == "detached": # NOTE(mriedem): save our current state so connection_info is in # the database before the volume status goes to 'in-use' because # after that we can detach and connection_info is required for # detach. self.save() volume_api.attach(context, volume_id, instance.uuid, self["mount_device"], mode=mode)
def attach(self, context, instance, volume_api, virt_driver, do_check_attach=True, do_driver_attach=False): volume = volume_api.get(context, self.volume_id) if do_check_attach: volume_api.check_attach(context, volume, instance=instance) volume_id = volume['id'] context = context.elevated() connector = virt_driver.get_volume_connector(instance) connection_info = volume_api.initialize_connection(context, volume_id, connector) if 'serial' not in connection_info: connection_info['serial'] = self.volume_id self._preserve_multipath_id(connection_info) # If do_driver_attach is False, we will attach a volume to an instance # at boot time. So actual attach is done by instance creation code. if do_driver_attach: encryption = encryptors.get_encryption_metadata( context, volume_api, volume_id, connection_info) try: virt_driver.attach_volume( context, connection_info, instance, self['mount_device'], disk_bus=self['disk_bus'], device_type=self['device_type'], encryption=encryption) except Exception: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Driver failed to attach volume " "%(volume_id)s at %(mountpoint)s"), {'volume_id': volume_id, 'mountpoint': self['mount_device']}, context=context, instance=instance) volume_api.terminate_connection(context, volume_id, connector) self['connection_info'] = connection_info mode = 'rw' if 'data' in connection_info: mode = connection_info['data'].get('access_mode', 'rw') if volume['attach_status'] == "detached": # NOTE(mriedem): save our current state so connection_info is in # the database before the volume status goes to 'in-use' because # after that we can detach and connection_info is required for # detach. self.save() volume_api.attach(context, volume_id, instance.uuid, self['mount_device'], mode=mode)
def attach(self, context, instance, volume_api, virt_driver, do_check_attach=True, do_driver_attach=False): volume = volume_api.get(context, self.volume_id) if do_check_attach: volume_api.check_attach(context, volume, instance=instance) volume_id = volume['id'] context = context.elevated() connector = virt_driver.get_volume_connector(instance) connection_info = volume_api.initialize_connection(context, volume_id, connector) if 'serial' not in connection_info: connection_info['serial'] = self.volume_id self._preserve_multipath_id(connection_info) # If do_driver_attach is False, we will attach a volume to an instance # at boot time. So actual attach is done by instance creation code. if do_driver_attach: encryption = encryptors.get_encryption_metadata( context, volume_api, volume_id, connection_info) try: virt_driver.attach_volume( context, connection_info, instance, self['mount_device'], disk_bus=self['disk_bus'], device_type=self['device_type'], encryption=encryption) except Exception: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Driver failed to attach volume " "%(volume_id)s at %(mountpoint)s"), {'volume_id': volume_id, 'mountpoint': self['mount_device']}, context=context, instance=instance) volume_api.terminate_connection(context, volume_id, connector) self['connection_info'] = connection_info mode = 'rw' if 'data' in connection_info: mode = connection_info['data'].get('access_mode', 'rw') if volume['attach_status'] == "detached": # NOTE(mriedem): save our current state so connection_info is in # the database before the volume status goes to 'in-use' because # after that we can detach and connection_info is required for # detach. self.save() volume_api.attach(context, volume_id, instance.uuid, self['mount_device'], mode=mode)
def attach(self, context, instance, volume_api, virt_driver, do_check_attach=True, do_driver_attach=False): volume = volume_api.get(context, self.volume_id) if do_check_attach: volume_api.check_attach(context, volume, instance=instance) volume_id = volume['id'] context = context.elevated() connector = virt_driver.get_volume_connector(instance) host = self._get_host(connector) connection_info = volume_api.initialize_connection(context, volume_id, connector, instance['uuid'], host) if 'serial' not in connection_info: connection_info['serial'] = self.volume_id self._preserve_multipath_id(connection_info) # If do_driver_attach is False, we will attach a volume to an instance # at boot time. So actual attach is done by instance creation code. if do_driver_attach: encryption = encryptors.get_encryption_metadata( context, volume_api, volume_id, connection_info) try: virt_driver.attach_volume( context, connection_info, instance, self['mount_device'], disk_bus=self['disk_bus'], device_type=self['device_type'], encryption=encryption) except Exception: # pylint: disable=W0702 with excutils.save_and_reraise_exception(): LOG.exception(_("Driver failed to attach volume " "%(volume_id)s at %(mountpoint)s"), {'volume_id': volume_id, 'mountpoint': self['mount_device']}, context=context, instance=instance) volume_api.terminate_connection(context, volume_id, connector, instance['uuid'], host) self['connection_info'] = connection_info mode = 'rw' if 'data' in connection_info: mode = connection_info['data'].get('access_mode', 'rw') volume_api.attach(context, volume_id, instance['uuid'], self['mount_device'], mode=mode)
def attach(self, context, instance, volume_api, virt_driver, do_check_attach=True, do_driver_attach=False): volume = volume_api.get(context, self.volume_id) if do_check_attach: volume_api.check_attach(context, volume, instance=instance) volume_id = volume["id"] context = context.elevated() connector = virt_driver.get_volume_connector(instance) connection_info = volume_api.initialize_connection(context, volume_id, connector) if "serial" not in connection_info: connection_info["serial"] = self.volume_id self._preserve_multipath_id(connection_info) # If do_driver_attach is False, we will attach a volume to an instance # at boot time. So actual attach is done by instance creation code. if do_driver_attach: encryption = encryptors.get_encryption_metadata(context, volume_api, volume_id, connection_info) try: virt_driver.attach_volume( context, connection_info, instance, self["mount_device"], disk_bus=self["disk_bus"], device_type=self["device_type"], encryption=encryption, ) except Exception: # pylint: disable=W0702 with excutils.save_and_reraise_exception(): LOG.exception( _("Driver failed to attach volume " "%(volume_id)s at %(mountpoint)s"), {"volume_id": volume_id, "mountpoint": self["mount_device"]}, context=context, instance=instance, ) volume_api.terminate_connection(context, volume_id, connector) self["connection_info"] = connection_info mode = "rw" if "data" in connection_info: mode = connection_info["data"].get("access_mode", "rw") if volume["attach_status"] == "detached": volume_api.attach(context, volume_id, instance["uuid"], self["mount_device"], mode=mode)
def driver_detach(self, context, instance, volume_api, virt_driver): connection_info = self['connection_info'] mp = self['mount_device'] volume_id = self.volume_id LOG.info(_LI('Attempting to driver detach volume %(volume_id)s from ' ' mountpoint %(mp)s'), { 'volume_id': volume_id, 'mp': mp }, instance=instance) try: if not virt_driver.instance_exists(instance): LOG.warning(_LW('Detaching volume from unknown instance'), instance=instance) encryption = encryptors.get_encryption_metadata( context, volume_api, volume_id, connection_info) virt_driver.detach_volume(connection_info, instance, mp, encryption=encryption) except exception.DiskNotFound as err: LOG.warning(_LW('Ignoring DiskNotFound exception while ' 'detaching volume %(volume_id)s from ' '%(mp)s : %(err)s'), { 'volume_id': volume_id, 'mp': mp, 'err': err }, instance=instance) except Exception: with excutils.save_and_reraise_exception(): LOG.exception(_LE('Failed to detach volume ' '%(volume_id)s from %(mp)s'), { 'volume_id': volume_id, 'mp': mp }, instance=instance) volume_api.roll_detaching(context, volume_id)
def _test_volume_attach(self, driver_bdm, bdm_dict, fake_volume, check_attach=True, fail_check_attach=False, driver_attach=False, fail_driver_attach=False, volume_attach=True, fail_volume_attach=False, access_mode='rw'): elevated_context = self.context.elevated() self.stubs.Set(self.context, 'elevated', lambda: elevated_context) self.mox.StubOutWithMock(driver_bdm._bdm_obj, 'save') self.mox.StubOutWithMock(encryptors, 'get_encryption_metadata') instance_detail = {'id': '123', 'uuid': 'fake_uuid'} instance = fake_instance.fake_instance_obj(self.context, **instance_detail) connector = {'ip': 'fake_ip', 'host': 'fake_host'} connection_info = {'data': {'access_mode': access_mode}} expected_conn_info = { 'data': { 'access_mode': access_mode }, 'serial': fake_volume['id'] } enc_data = {'fake': 'enc_data'} self.volume_api.get(self.context, fake_volume['id']).AndReturn(fake_volume) if check_attach: if not fail_check_attach: self.volume_api.check_attach(self.context, fake_volume, instance=instance).AndReturn(None) else: self.volume_api.check_attach(self.context, fake_volume, instance=instance).AndRaise( test.TestingException) driver_bdm._bdm_obj.save().AndReturn(None) return instance, expected_conn_info self.virt_driver.get_volume_connector(instance).AndReturn(connector) self.volume_api.initialize_connection( elevated_context, fake_volume['id'], connector).AndReturn(connection_info) if driver_attach: encryptors.get_encryption_metadata( elevated_context, self.volume_api, fake_volume['id'], connection_info).AndReturn(enc_data) if not fail_driver_attach: self.virt_driver.attach_volume( elevated_context, expected_conn_info, instance, bdm_dict['device_name'], disk_bus=bdm_dict['disk_bus'], device_type=bdm_dict['device_type'], encryption=enc_data).AndReturn(None) else: self.virt_driver.attach_volume( elevated_context, expected_conn_info, instance, bdm_dict['device_name'], disk_bus=bdm_dict['disk_bus'], device_type=bdm_dict['device_type'], encryption=enc_data).AndRaise(test.TestingException) self.volume_api.terminate_connection(elevated_context, fake_volume['id'], connector).AndReturn(None) driver_bdm._bdm_obj.save().AndReturn(None) return instance, expected_conn_info if volume_attach: driver_bdm._bdm_obj.save().AndReturn(None) if not fail_volume_attach: self.volume_api.attach(elevated_context, fake_volume['id'], 'fake_uuid', bdm_dict['device_name'], mode=access_mode).AndReturn(None) else: self.volume_api.attach(elevated_context, fake_volume['id'], 'fake_uuid', bdm_dict['device_name'], mode=access_mode).AndRaise( test.TestingException) driver_bdm._bdm_obj.save().AndReturn(None) return instance, expected_conn_info
def _test_volume_attach(self, driver_bdm, bdm_dict, fake_volume, check_attach=True, fail_check_attach=False, driver_attach=False, fail_driver_attach=False, volume_attach=True, access_mode='rw'): elevated_context = self.context.elevated() self.stubs.Set(self.context, 'elevated', lambda: elevated_context) self.mox.StubOutWithMock(driver_bdm._bdm_obj, 'save') self.mox.StubOutWithMock(encryptors, 'get_encryption_metadata') instance = {'id': 'fake_id', 'uuid': 'fake_uuid'} connector = {'ip': 'fake_ip', 'host': 'fake_host'} connection_info = {'data': {'access_mode': access_mode}} expected_conn_info = {'data': {'access_mode': access_mode}, 'serial': fake_volume['id']} enc_data = {'fake': 'enc_data'} self.volume_api.get(self.context, fake_volume['id']).AndReturn(fake_volume) if check_attach: if not fail_check_attach: self.volume_api.check_attach(self.context, fake_volume, instance=instance).AndReturn(None) else: self.volume_api.check_attach(self.context, fake_volume, instance=instance).AndRaise( test.TestingException) return instance, expected_conn_info self.virt_driver.get_volume_connector(instance).AndReturn(connector) self.volume_api.initialize_connection( elevated_context, fake_volume['id'], connector).AndReturn(connection_info) if driver_attach: encryptors.get_encryption_metadata( elevated_context, self.volume_api, fake_volume['id'], connection_info).AndReturn(enc_data) if not fail_driver_attach: self.virt_driver.attach_volume( elevated_context, expected_conn_info, instance, bdm_dict['device_name'], disk_bus=bdm_dict['disk_bus'], device_type=bdm_dict['device_type'], encryption=enc_data).AndReturn(None) else: self.virt_driver.attach_volume( elevated_context, expected_conn_info, instance, bdm_dict['device_name'], disk_bus=bdm_dict['disk_bus'], device_type=bdm_dict['device_type'], encryption=enc_data).AndRaise(test.TestingException) self.volume_api.terminate_connection( elevated_context, fake_volume['id'], expected_conn_info).AndReturn(None) return instance, expected_conn_info if volume_attach: self.volume_api.attach(elevated_context, fake_volume['id'], 'fake_uuid', bdm_dict['device_name'], mode=access_mode).AndReturn(None) # NOTE(mriedem): save() is called with the elevated context within # attach() and with the original context from the update_db decorator # so we ignore which arg it is in test. driver_bdm._bdm_obj.save( mox.IgnoreArg()).MultipleTimes().AndReturn(None) return instance, expected_conn_info
def _test_volume_attach(self, driver_bdm, bdm_dict, fake_volume, check_attach=True, fail_check_attach=False, driver_attach=False, fail_driver_attach=False, volume_attach=True, access_mode='rw'): elevated_context = self.context.elevated() self.stubs.Set(self.context, 'elevated', lambda: elevated_context) self.mox.StubOutWithMock(driver_bdm._bdm_obj, 'save') self.mox.StubOutWithMock(encryptors, 'get_encryption_metadata') instance = {'id': 'fake_id', 'uuid': 'fake_uuid'} connector = {'ip': 'fake_ip', 'host': 'fake_host'} connection_info = {'data': {'access_mode': access_mode}} expected_conn_info = { 'data': { 'access_mode': access_mode }, 'serial': fake_volume['id'] } enc_data = {'fake': 'enc_data'} self.volume_api.get(self.context, fake_volume['id']).AndReturn(fake_volume) if check_attach: if not fail_check_attach: self.volume_api.check_attach(self.context, fake_volume, instance=instance).AndReturn(None) else: self.volume_api.check_attach(self.context, fake_volume, instance=instance).AndRaise( test.TestingException) return instance, expected_conn_info self.virt_driver.get_volume_connector(instance).AndReturn(connector) self.volume_api.initialize_connection( elevated_context, fake_volume['id'], connector).AndReturn(connection_info) if driver_attach: encryptors.get_encryption_metadata( elevated_context, self.volume_api, fake_volume['id'], connection_info).AndReturn(enc_data) if not fail_driver_attach: self.virt_driver.attach_volume( elevated_context, expected_conn_info, instance, bdm_dict['device_name'], disk_bus=bdm_dict['disk_bus'], device_type=bdm_dict['device_type'], encryption=enc_data).AndReturn(None) else: self.virt_driver.attach_volume( elevated_context, expected_conn_info, instance, bdm_dict['device_name'], disk_bus=bdm_dict['disk_bus'], device_type=bdm_dict['device_type'], encryption=enc_data).AndRaise(test.TestingException) self.volume_api.terminate_connection( elevated_context, fake_volume['id'], expected_conn_info).AndReturn(None) return instance, expected_conn_info if volume_attach: self.volume_api.attach(elevated_context, fake_volume['id'], 'fake_uuid', bdm_dict['device_name'], mode=access_mode).AndReturn(None) # NOTE(mriedem): save() is called with the elevated context within # attach() and with the original context from the update_db decorator # so we ignore which arg it is in test. driver_bdm._bdm_obj.save( mox.IgnoreArg()).MultipleTimes().AndReturn(None) return instance, expected_conn_info
def _test_volume_attach( self, driver_bdm, bdm_dict, fake_volume, check_attach=True, fail_check_attach=False, driver_attach=False, fail_driver_attach=False, volume_attach=True, fail_volume_attach=False, access_mode="rw", availability_zone=None, ): elevated_context = self.context.elevated() self.stubs.Set(self.context, "elevated", lambda: elevated_context) self.mox.StubOutWithMock(driver_bdm._bdm_obj, "save") self.mox.StubOutWithMock(encryptors, "get_encryption_metadata") instance_detail = {"id": "123", "uuid": "fake_uuid", "availability_zone": availability_zone} instance = fake_instance.fake_instance_obj(self.context, **instance_detail) connector = {"ip": "fake_ip", "host": "fake_host"} connection_info = {"data": {"access_mode": access_mode}} expected_conn_info = {"data": {"access_mode": access_mode}, "serial": fake_volume["id"]} enc_data = {"fake": "enc_data"} self.volume_api.get(self.context, fake_volume["id"]).AndReturn(fake_volume) if check_attach: if not fail_check_attach: self.volume_api.check_attach(self.context, fake_volume, instance=instance).AndReturn(None) else: self.volume_api.check_attach(self.context, fake_volume, instance=instance).AndRaise( test.TestingException ) driver_bdm._bdm_obj.save().AndReturn(None) return instance, expected_conn_info self.virt_driver.get_volume_connector(instance).AndReturn(connector) self.volume_api.initialize_connection(elevated_context, fake_volume["id"], connector).AndReturn(connection_info) if driver_attach: encryptors.get_encryption_metadata( elevated_context, self.volume_api, fake_volume["id"], connection_info ).AndReturn(enc_data) if not fail_driver_attach: self.virt_driver.attach_volume( elevated_context, expected_conn_info, instance, bdm_dict["device_name"], disk_bus=bdm_dict["disk_bus"], device_type=bdm_dict["device_type"], encryption=enc_data, ).AndReturn(None) else: self.virt_driver.attach_volume( elevated_context, expected_conn_info, instance, bdm_dict["device_name"], disk_bus=bdm_dict["disk_bus"], device_type=bdm_dict["device_type"], encryption=enc_data, ).AndRaise(test.TestingException) self.volume_api.terminate_connection(elevated_context, fake_volume["id"], connector).AndReturn(None) driver_bdm._bdm_obj.save().AndReturn(None) return instance, expected_conn_info if volume_attach: driver_bdm._bdm_obj.save().AndReturn(None) if not fail_volume_attach: self.volume_api.attach( elevated_context, fake_volume["id"], "fake_uuid", bdm_dict["device_name"], mode=access_mode ).AndReturn(None) else: self.volume_api.attach( elevated_context, fake_volume["id"], "fake_uuid", bdm_dict["device_name"], mode=access_mode ).AndRaise(test.TestingException) if driver_attach: self.virt_driver.detach_volume( expected_conn_info, instance, bdm_dict["device_name"], encryption=enc_data ).AndReturn(None) self.volume_api.terminate_connection(elevated_context, fake_volume["id"], connector).AndReturn(None) self.volume_api.detach(elevated_context, fake_volume["id"]).AndReturn(None) driver_bdm._bdm_obj.save().AndReturn(None) return instance, expected_conn_info
def attach(self, context, instance, volume_api, virt_driver, do_check_attach=True, do_driver_attach=False, **kwargs): volume = volume_api.get(context, self.volume_id) if do_check_attach: volume_api.check_attach(context, volume, instance=instance) volume_id = volume['id'] vol_multiattach = volume.get('multiattach', False) has_attachments = bool(volume.get('attachments')) virt_multiattach = virt_driver.capabilities['supports_multiattach'] if vol_multiattach and has_attachments and not virt_multiattach: raise exception.MultiattachNotSupported(volume_id=volume_id) context = context.elevated() connector = virt_driver.get_volume_connector(instance) connection_info = volume_api.initialize_connection( context, volume_id, connector) if 'serial' not in connection_info: connection_info['serial'] = self.volume_id self._preserve_multipath_id(connection_info) if vol_multiattach and virt_multiattach: connection_info['multiattach'] = True # If do_driver_attach is False, we will attach a volume to an instance # at boot time. So actual attach is done by instance creation code. if do_driver_attach: encryption = encryptors.get_encryption_metadata( context, volume_api, volume_id, connection_info) try: virt_driver.attach_volume(context, connection_info, instance, self['mount_device'], disk_bus=self['disk_bus'], device_type=self['device_type'], encryption=encryption) except Exception: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Driver failed to attach volume " "%(volume_id)s at %(mountpoint)s"), { 'volume_id': volume_id, 'mountpoint': self['mount_device'] }, context=context, instance=instance) volume_api.check_and_terminate_connection( context, volume_id, connector, instance.host) self['connection_info'] = connection_info if self.volume_size is None: self.volume_size = volume.get('size') mode = 'rw' if 'data' in connection_info: mode = connection_info['data'].get('access_mode', 'rw') if (volume['attach_status'] == "detached" or volume['attach_status'] == 'attached' and vol_multiattach): # NOTE(mriedem): save our current state so connection_info is in # the database before the volume status goes to 'in-use' because # after that we can detach and connection_info is required for # detach. self.save() try: volume_api.attach(context, volume_id, instance.uuid, self['mount_device'], mode=mode) except Exception: with excutils.save_and_reraise_exception(): if do_driver_attach: try: virt_driver.detach_volume(connection_info, instance, self['mount_device'], encryption=encryption) except Exception: LOG.warn(_LW("Driver failed to detach volume " "%(volume_id)s at %(mount_point)s."), { 'volume_id': volume_id, 'mount_point': self['mount_device'] }, exc_info=True, context=context, instance=instance) volume_api.check_and_terminate_connection( context, volume_id, connector, instance.host) # Cinder-volume might have completed volume attach. So # we should detach the volume. If the attach did not # happen, the detach request will be ignored. volume_api.detach(context, volume_id)
def attach(self, context, instance, volume_api, virt_driver, do_check_attach=True, do_driver_attach=False, **kwargs): volume = volume_api.get(context, self.volume_id) if do_check_attach: #song.w 12.25 volume_api.check_attach(context, volume, instance=instance) #pass volume_id = volume['id'] context = context.elevated() connector = virt_driver.get_volume_connector(instance) connection_info = volume_api.initialize_connection(context, volume_id, connector) if 'serial' not in connection_info: connection_info['serial'] = self.volume_id self._preserve_multipath_id(connection_info) # If do_driver_attach is False, we will attach a volume to an instance # at boot time. So actual attach is done by instance creation code. if do_driver_attach: encryption = encryptors.get_encryption_metadata( context, volume_api, volume_id, connection_info) try: virt_driver.attach_volume( context, connection_info, instance, self['mount_device'], disk_bus=self['disk_bus'], device_type=self['device_type'], encryption=encryption) except Exception: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Driver failed to attach volume " "%(volume_id)s at %(mountpoint)s"), {'volume_id': volume_id, 'mountpoint': self['mount_device']}, instance=instance) volume_api.terminate_connection(context, volume_id, connector) self['connection_info'] = connection_info if self.volume_size is None: self.volume_size = volume.get('size') mode = 'rw' if 'data' in connection_info: mode = connection_info['data'].get('access_mode', 'rw') ##song.w modify 2017-12-26 #Support the status of multiple mounts scenarios #begin if volume['multiattach']: if volume['attach_status'] == "detached" or volume['attach_status'] == "attached": self.save() try: volume_api.attach(context, volume_id, instance.uuid, self['mount_device'], mode=mode) except Exception: with excutils.save_and_reraise_exception(): if do_driver_attach: try: virt_driver.detach_volume(connection_info, instance, self['mount_device'], encryption=encryption) except Exception: LOG.warning(_LW("Driver failed to detach volume " "%(volume_id)s at %(mount_point)s."), {'volume_id': volume_id, 'mount_point': self['mount_device']}, exc_info=True, instance=instance) volume_api.terminate_connection(context, volume_id, connector) # Cinder-volume might have completed volume attach. So # we should detach the volume. If the attach did not # happen, the detach request will be ignored. volume_api.detach(context, volume_id) else: if volume['attach_status'] == "detached": # NOTE(mriedem): save our current state so connection_info is in # the database before the volume status goes to 'in-use' because # after that we can detach and connection_info is required for # detach. self.save() try: volume_api.attach(context, volume_id, instance.uuid, self['mount_device'], mode=mode) except Exception: with excutils.save_and_reraise_exception(): if do_driver_attach: try: virt_driver.detach_volume(connection_info, instance, self['mount_device'], encryption=encryption) except Exception: LOG.warning(_LW("Driver failed to detach volume " "%(volume_id)s at %(mount_point)s."), {'volume_id': volume_id, 'mount_point': self['mount_device']}, exc_info=True, instance=instance) volume_api.terminate_connection(context, volume_id, connector) # Cinder-volume might have completed volume attach. So # we should detach the volume. If the attach did not # happen, the detach request will be ignored. volume_api.detach(context, volume_id) # Support the status of multiple mounts scenarios # end """