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 _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, 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