def check_ret_val(self, ret_val, job_path, success_values=[0]): """Checks that the job represented by the given arguments succeeded. Some Hyper-V operations are not atomic, and will return a reference to a job. In this case, this method will wait for the job's completion. :param ret_val: integer, representing the return value of the job. if the value is WMI_JOB_STATUS_STARTED or WMI_JOB_STATE_RUNNING, a job_path cannot be None. :param job_path: string representing the WMI object path of a Hyper-V job. :param success_values: list of return values that can be considered successful. WMI_JOB_STATUS_STARTED and WMI_JOB_STATE_RUNNING values are ignored. :raises exceptions.WMIJobFailed: if the given ret_val is WMI_JOB_STATUS_STARTED or WMI_JOB_STATE_RUNNING and the state of job represented by the given job_path is not WMI_JOB_STATE_COMPLETED or JOB_STATE_COMPLETED_WITH_WARNINGS, or if the given ret_val is not in the list of given success_values. """ if ret_val in [ constants.WMI_JOB_STATUS_STARTED, constants.WMI_JOB_STATE_RUNNING ]: return self._wait_for_job(job_path) elif ret_val not in success_values: raise exceptions.WMIJobFailed(error_code=ret_val, job_state=None, error_summ_desc=None, error_desc=None)
def _wait_for_job(self, job_path): """Poll WMI job state and wait for completion.""" job_wmi_path = job_path.replace('\\', '/') job = self._get_wmi_obj(job_wmi_path) # We'll log the job status from time to time. last_report_time = 0 report_interval = 5 while not self._is_job_completed(job): now = monotonic.monotonic() if now - last_report_time > report_interval: job_details = self._get_job_details(job) LOG.debug("Waiting for WMI job: %s.", job_details) last_report_time = now time.sleep(0.1) job = self._get_wmi_obj(job_wmi_path) job_state = job.JobState err_code = job.ErrorCode # We'll raise an exception for killed jobs. job_failed = job_state not in self._successful_job_states or err_code job_warnings = job_state == constants.JOB_STATE_COMPLETED_WITH_WARNINGS job_details = self._get_job_details(job, extended=(job_failed or job_warnings)) if job_failed: err_sum_desc = getattr(job, 'ErrorSummaryDescription', None) err_desc = job.ErrorDescription LOG.error("WMI job failed: %s.", job_details) raise exceptions.WMIJobFailed(job_state=job_state, error_code=err_code, error_summ_desc=err_sum_desc, error_desc=err_desc) if job_warnings: LOG.warning( "WMI job completed with warnings. For detailed " "information, please check the Windows event logs. " "Job details: %s.", job_details) else: LOG.debug("WMI job succeeded: %s.", job_details) return job