示例#1
0
    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)
示例#2
0
    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)
示例#3
0
    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
示例#4
0
    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