Beispiel #1
0
    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)
Beispiel #2
0
    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