예제 #1
0
    def _stop_jobs(self, element):
        pending_jobs = self._get_pending_jobs_affecting_element(element)
        for job in pending_jobs:
            job_details = self._get_job_details(job, extended=True)
            try:
                if not job.Cancellable:
                    LOG.debug(
                        "Got request to terminate "
                        "non-cancelable job: %s.", job_details)
                    continue

                job.RequestStateChange(self._KILL_JOB_STATE_CHANGE_REQUEST)
            except exceptions.x_wmi as ex:
                # The job may had been completed right before we've
                # attempted to kill it.
                if not _utils._is_not_found_exc(ex):
                    LOG.debug(
                        "Failed to stop job. Exception: %s. "
                        "Job details: %s.", ex, job_details)

        pending_jobs = self._get_pending_jobs_affecting_element(element)
        if pending_jobs:
            pending_job_details = [
                self._get_job_details(job, extended=True)
                for job in pending_jobs
            ]
            LOG.debug(
                "Attempted to terminate jobs "
                "affecting element %(element)s but "
                "%(pending_count)s jobs are still pending: "
                "%(pending_jobs)s.",
                dict(element=element,
                     pending_count=len(pending_jobs),
                     pending_jobs=pending_job_details))
            raise exceptions.JobTerminateFailed()
예제 #2
0
    def _stop_jobs(self, element):
        pending_jobs = self._get_pending_jobs_affecting_element(
            element, ignore_error_state=False)
        for job in pending_jobs:
            try:
                if not job.Cancellable:
                    LOG.debug("Got request to terminate "
                              "non-cancelable job.")
                    continue
                elif job.JobState == constants.JOB_STATE_EXCEPTION:
                    LOG.debug("Attempting to terminate exception state job.")

                job.RequestStateChange(self._KILL_JOB_STATE_CHANGE_REQUEST)
            except exceptions.x_wmi as ex:
                hresult = win32utils.Win32Utils.get_com_error_hresult(
                    ex.com_error)
                # The job may had been completed right before we've
                # attempted to kill it.
                if not hresult == self._WBEM_E_NOT_FOUND:
                    LOG.debug("Failed to stop job. Exception: %s", ex)

        pending_jobs = self._get_pending_jobs_affecting_element(element)
        if pending_jobs:
            LOG.debug(
                "Attempted to terminate jobs "
                "affecting element %(element)s but "
                "%(pending_count)s jobs are still pending.",
                dict(element=element, pending_count=len(pending_jobs)))
            raise exceptions.JobTerminateFailed()
예제 #3
0
    def test_cancel_cluster_group_migration(self, mock_wait_migr,
                                            mock_is_migr_pending,
                                            mock_get_gr_state,
                                            cancel_still_pending=False,
                                            cancel_exception=None,
                                            invalid_state_for_cancel=False,
                                            cancel_wait_exception=None):
        expected_exception = None
        if cancel_wait_exception:
            expected_exception = exceptions.JobTerminateFailed()
        if (cancel_exception and (not invalid_state_for_cancel
                                  or cancel_still_pending)):
            expected_exception = cancel_exception

        mock_is_migr_pending.return_value = cancel_still_pending
        mock_get_gr_state.return_value = dict(
            state=mock.sentinel.state,
            status_info=mock.sentinel.status_info)

        self._clusapi.cancel_cluster_group_operation.side_effect = (
            cancel_exception or (not cancel_still_pending, ))
        mock_wait_migr.side_effect = cancel_wait_exception

        cancel_args = (mock.sentinel.listener,
                       mock.sentinel.group_name,
                       mock.sentinel.group_handle,
                       mock.sentinel.expected_state,
                       mock.sentinel.timeout)
        if expected_exception:
            self.assertRaises(
                expected_exception.__class__,
                self._clusterutils._cancel_cluster_group_migration,
                *cancel_args)
        else:
            self._clusterutils._cancel_cluster_group_migration(
                *cancel_args)

        self._clusapi.cancel_cluster_group_operation.assert_called_once_with(
            mock.sentinel.group_handle)

        if isinstance(cancel_exception, exceptions.Win32Exception):
            mock_get_gr_state.assert_called_once_with(
                mock.sentinel.group_handle)
            mock_is_migr_pending.assert_called_once_with(
                mock.sentinel.state,
                mock.sentinel.status_info,
                mock.sentinel.expected_state)
        if cancel_still_pending and not cancel_exception:
            mock_wait_migr.assert_called_once_with(
                mock.sentinel.listener,
                mock.sentinel.group_name,
                mock.sentinel.group_handle,
                mock.sentinel.expected_state,
                timeout=mock.sentinel.timeout)
예제 #4
0
    def _cancel_cluster_group_migration(self,
                                        event_listener,
                                        group_name,
                                        group_handle,
                                        expected_state,
                                        timeout=None):
        LOG.info("Canceling cluster group '%s' migration", group_name)
        try:
            cancel_finished = (self._clusapi_utils.
                               cancel_cluster_group_operation(group_handle))
        except exceptions.Win32Exception as ex:
            group_state_info = self._get_cluster_group_state(group_handle)
            migration_pending = self._is_migration_pending(
                group_state_info['state'], group_state_info['status_info'],
                expected_state)

            if (ex.error_code == w_const.ERROR_INVALID_STATE
                    and not migration_pending):
                LOG.debug('Ignoring group migration cancel error. '
                          'No migration is pending.')
                cancel_finished = True
            else:
                raise

        if not cancel_finished:
            LOG.debug("Waiting for group migration to be canceled.")
            try:
                self._wait_for_cluster_group_migration(event_listener,
                                                       group_name,
                                                       group_handle,
                                                       expected_state,
                                                       timeout=timeout)
            except Exception:
                LOG.exception("Failed to cancel cluster group migration.")
                raise exceptions.JobTerminateFailed()

        LOG.info("Cluster group migration canceled.")