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()
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()
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)
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.")