示例#1
0
    def test_power_off_negative(self, mock_power_off):
        """Negative tests."""

        # Raise the expected pypowervm exception
        mock_power_off.side_effect = pvm_exc.VMPowerOffFailure(
            reason='Something bad.', lpar_nm='TheLPAR')
        # We should get a valid Nova exception that the compute manager expects
        self.assertRaises(exception.InstancePowerOffFailure,
                          vm.power_off, None, None, 'host_uuid',
                          mock.Mock(state=pvm_bp.LPARState.RUNNING))
示例#2
0
    def test_power_off_negative(self, mock_wrap, mock_power_off):
        """Negative tests."""
        instance = objects.Instance(**powervm.TEST_INSTANCE)
        mock_wrap.return_value = mock.Mock(state=pvm_bp.LPARState.RUNNING)

        # Raise the expected pypowervm exception
        mock_power_off.side_effect = pvm_exc.VMPowerOffFailure(
            reason='Something bad.', lpar_nm='TheLPAR')
        # We should get a valid Nova exception that the compute manager expects
        self.assertRaises(exception.InstancePowerOffFailure, vm.power_off,
                          None, instance)
    def test_power_off_negative(self, mock_wrap, mock_power_off):
        """Negative tests."""
        mock_wrap.return_value = mock.Mock(state=pvm_bp.LPARState.RUNNING)

        # Raise the expected pypowervm exception
        mock_power_off.side_effect = pvm_exc.VMPowerOffFailure(
            reason='Something bad.', lpar_nm='TheLPAR')
        # We should get a valid Nova exception that the compute manager expects
        self.assertRaises(exception.InstancePowerOffFailure, vm.power_off,
                          None, self.inst)

        # Non-pvm error raises directly
        mock_power_off.side_effect = ValueError()
        self.assertRaises(ValueError, vm.power_off, None, self.inst)
示例#4
0
    def stop(cls,
             part,
             opts=None,
             timeout=CONF.pypowervm_job_request_timeout,
             synchronous=True):
        """Power off a partition.

        :param part: LPAR/VIOS wrapper indicating the partition to power off.
        :param opts: An instance of power_opts.PowerOffOpts indicating the type
                     of shutdown to perform, and any additional options.  If
                     not specified, PowerOffOpts.soft_detect is used, with no
                     restart.
        :param timeout: value in seconds for specifying how long to wait for
                        the Job to complete.
        :param synchronous: If True, this method will not return until the Job
                            completes (whether success or failure) or times
                            out.  If False, this method will return as soon as
                            the Job has started on the server (that is,
                            achieved any state beyond NOT_ACTIVE).  Note that
                            timeout is still possible in this case.
        :raise VMPowerOffTimeout: If the Job timed out.
        :raise VMPowerOffFailure: If the Job failed for some reason other than
                                  that the partition was already powered off,
                                  and restart was not requested.
        :return: A PowerOp instance which can be invoked via the run method.
        :raise OSShutdownNoRMC: OP_PWROFF_OS was requested on a non-IBMi
                                partition with no RMC connection.
        """
        if opts is None:
            opts = popts.PowerOffOpts().soft_detect(part)

        if opts.is_os and not opts.can_os_shutdown(part):
            raise pexc.OSShutdownNoRMC(lpar_nm=part.name)

        try:
            cls._run(part, opts, timeout, synchronous=synchronous)
        except pexc.JobRequestTimedOut as error:
            LOG.exception(error)
            raise pexc.VMPowerOffTimeout(lpar_nm=part.name, timeout=timeout)
        except pexc.JobRequestFailed as error:
            emsg = six.text_type(error)
            # If already powered off and not a reboot, don't send exception
            if (any(err_prefix in emsg
                    for err_prefix in _ALREADY_POWERED_OFF_ERRS)
                    and not opts.is_restart):
                LOG.warning(_("Partition %s already powered off."), part.name)
                return
            LOG.exception(error)
            raise pexc.VMPowerOffFailure(lpar_nm=part.name, reason=emsg)
示例#5
0
def _power_on_off(part, suffix, host_uuid, force_immediate=Force.ON_FAILURE,
                  restart=False, timeout=CONF.pypowervm_job_request_timeout,
                  add_parms=None, synchronous=True):
    """Internal function to power on or off an instance.

    :param part: The LPAR/VIOS wrapper of the instance to act on.
    :param suffix: power option - 'PowerOn' or 'PowerOff'.
    :param host_uuid: TEMPORARY - The host system UUID that the LPAR/VIOS
                      resides on
    :param force_immediate: (For PowerOff suffix only) One of the Force enum
                            values (defaulting to Force.ON_FAILURE), which
                            behave as follows:
            - Force.TRUE: The force-immediate option is included on the first
                          pass.
            - Force.NO_RETRY: The force-immediate option is not included.  If
                              the power-off fails or times out,
                              VMPowerOffFailure is raised immediately.
            - Force.ON_FAILURE: The force-immediate option is not included on
                                the first pass; but if the power-off fails
                                (including timeout), it is retried with the
                                force-immediate option added.
    :param restart: Boolean.  Do a restart after power off (for PowerOff suffix
                    only)
    :param timeout: Value in seconds for specifying how long to wait for the
                    LPAR/VIOS to stop (for PowerOff suffix only)
    :param add_parms: dict of parameters to pass directly to the job template
    :param synchronous: If True (the default), this method will not return
                        until the Job completes (whether success or failure) or
                        times out.  If False, this method will return as soon
                        as the Job has started on the server (that is, achieved
                        any state beyond NOT_ACTIVE).  Note that timeout is
                        still possible in this case.
    """
    complete = False
    uuid = part.uuid
    adapter = part.adapter
    normal_vsp_power_off = False
    add_immediate = part.env != bp.LPARType.OS400
    while not complete:
        resp = adapter.read(part.schema_type, uuid,
                            suffix_type=c.SUFFIX_TYPE_DO,
                            suffix_parm=suffix)
        job_wrapper = job.Job.wrap(resp.entry)
        job_parms = []
        if suffix == _SUFFIX_PARM_POWER_OFF:
            operation = 'osshutdown'
            if force_immediate == Force.TRUE:
                operation = 'shutdown'
                add_immediate = True
            # Do normal vsp shutdown if flag on or
            # if RMC not active (for non-IBMi)
            elif (normal_vsp_power_off or
                  (part.env != bp.LPARType.OS400 and
                   part.rmc_state != bp.RMCState.ACTIVE)):
                operation = 'shutdown'
                add_immediate = False
            job_parms.append(
                job_wrapper.create_job_parameter('operation', operation))
            if add_immediate:
                job_parms.append(
                    job_wrapper.create_job_parameter('immediate', 'true'))
            if restart:
                job_parms.append(
                    job_wrapper.create_job_parameter('restart', 'true'))

        # Add add_parms to the job
        if add_parms is not None:
            for kw in add_parms.keys():
                # Skip any parameters already set.
                if kw not in ['operation', 'immediate', 'restart']:
                    job_parms.append(job_wrapper.create_job_parameter(
                        kw, str(add_parms[kw])))
        try:
            job_wrapper.run_job(uuid, job_parms=job_parms, timeout=timeout,
                                synchronous=synchronous)
            complete = True
        except pexc.JobRequestTimedOut as error:
            if suffix == _SUFFIX_PARM_POWER_OFF:
                if operation == 'osshutdown' and (force_immediate ==
                                                  Force.ON_FAILURE):
                    # This has timed out, we loop again and attempt to
                    # force immediate vsp. Unless IBMi, in which case we
                    # will try an immediate osshutdown and then
                    # a vsp normal before then jumping to immediate vsp.
                    timeout = CONF.pypowervm_job_request_timeout
                    if part.env == bp.LPARType.OS400:
                        if not add_immediate:
                            add_immediate = True
                        else:
                            normal_vsp_power_off = True
                    else:
                        force_immediate = Force.TRUE
                # normal vsp power off did not work, try hard vsp power off
                elif normal_vsp_power_off:
                    timeout = CONF.pypowervm_job_request_timeout
                    force_immediate = Force.TRUE
                    normal_vsp_power_off = False
                else:
                    LOG.exception(error)
                    emsg = six.text_type(error)
                    raise pexc.VMPowerOffFailure(reason=emsg,
                                                 lpar_nm=part.name)
            else:
                # Power On timed out
                LOG.exception(error)
                emsg = six.text_type(error)
                raise pexc.VMPowerOnFailure(reason=emsg, lpar_nm=part.name)
        except pexc.JobRequestFailed as error:
            emsg = six.text_type(error)
            LOG.exception(_('Error: %s') % emsg)
            if suffix == _SUFFIX_PARM_POWER_OFF:
                # If already powered off and not a reboot,
                # don't send exception
                if (any(err_prefix in emsg
                        for err_prefix in _ALREADY_POWERED_OFF_ERRS) and
                        not restart):
                    complete = True
                # If failed for other reasons,
                # retry with normal vsp power off except for IBM i
                # where we try immediate osshutdown first
                elif operation == 'osshutdown' and (force_immediate ==
                                                    Force.ON_FAILURE):
                    timeout = CONF.pypowervm_job_request_timeout
                    if (part.env == bp.LPARType.OS400 and not add_immediate):
                        add_immediate = True
                    else:
                        force_immediate = Force.NO_RETRY
                        normal_vsp_power_off = True
                # normal vsp power off did not work, try hard vsp power off
                elif normal_vsp_power_off:
                    timeout = CONF.pypowervm_job_request_timeout
                    force_immediate = Force.TRUE
                    normal_vsp_power_off = False
                else:
                    raise pexc.VMPowerOffFailure(reason=emsg,
                                                 lpar_nm=part.name)
            else:
                # If already powered on, don't send exception
                if (any(err_prefix in emsg
                        for err_prefix in _ALREADY_POWERED_ON_ERRS)):
                    complete = True
                else:
                    raise pexc.VMPowerOnFailure(reason=emsg, lpar_nm=part.name)
示例#6
0
def _power_on_off(part,
                  suffix,
                  host_uuid,
                  force_immediate=False,
                  restart=False,
                  timeout=CONF.pypowervm_job_request_timeout,
                  add_parms=None,
                  synchronous=True):
    """Internal function to power on or off an instance.

    :param part: The LPAR/VIOS wrapper of the instance to act on.
    :param suffix: power option - 'PowerOn' or 'PowerOff'.
    :param host_uuid: TEMPORARY - The host system UUID that the LPAR/VIOS
                      resides on
    :param force_immediate: Boolean.  Do immediate shutdown (for PowerOff
                            suffix only)
    :param restart: Boolean.  Do a restart after power off (for PowerOff suffix
                    only)
    :param timeout: Value in seconds for specifying how long to wait for the
                    LPAR/VIOS to stop (for PowerOff suffix only)
    :param add_parms: dict of parameters to pass directly to the job template
    :param synchronous: If True (the default), this method will not return
                        until the Job completes (whether success or failure) or
                        times out.  If False, this method will return as soon
                        as the Job has started on the server (that is, achieved
                        any state beyond NOT_ACTIVE).  Note that timeout is
                        still possible in this case.
    """
    complete = False
    uuid = part.uuid
    adapter = part.adapter
    normal_vsp_power_off = False
    add_immediate = part.env != bp.LPARType.OS400
    try:
        while not complete:
            resp = adapter.read(part.schema_type,
                                uuid,
                                suffix_type=c.SUFFIX_TYPE_DO,
                                suffix_parm=suffix)
            job_wrapper = job.Job.wrap(resp.entry)
            job_parms = []
            if suffix == _SUFFIX_PARM_POWER_OFF:
                operation = 'osshutdown'
                if force_immediate:
                    operation = 'shutdown'
                    add_immediate = True
                # Do normal vsp shutdown if flag on or
                # if RMC not active (for non-IBMi)
                elif (normal_vsp_power_off
                      or (part.env != bp.LPARType.OS400
                          and part.rmc_state != bp.RMCState.ACTIVE)):
                    operation = 'shutdown'
                    add_immediate = False
                job_parms.append(
                    job_wrapper.create_job_parameter('operation', operation))
                if add_immediate:
                    job_parms.append(
                        job_wrapper.create_job_parameter('immediate', 'true'))
                if restart:
                    job_parms.append(
                        job_wrapper.create_job_parameter('restart', 'true'))

            # Add add_parms to the job
            if add_parms is not None:
                for kw in add_parms.keys():
                    # Skip any parameters already set.
                    if kw not in ['operation', 'immediate', 'restart']:
                        job_parms.append(
                            job_wrapper.create_job_parameter(
                                kw, str(add_parms[kw])))
            try:
                job_wrapper.run_job(uuid,
                                    job_parms=job_parms,
                                    timeout=timeout,
                                    synchronous=synchronous)
                complete = True
            except pexc.JobRequestTimedOut as error:
                if (suffix == _SUFFIX_PARM_POWER_OFF
                        and operation == 'osshutdown'):
                    # This has timed out, we loop again and attempt to
                    # force immediate vsp now except for IBM i where we try
                    # immediate osshutdown first
                    timeout = CONF.pypowervm_job_request_timeout
                    if (part.env == bp.LPARType.OS400 and not add_immediate):
                        add_immediate = True
                    else:
                        force_immediate = True
                else:
                    emsg = six.text_type(error)
                    LOG.exception(_('Error: %s') % emsg)
                    if suffix == _SUFFIX_PARM_POWER_OFF:
                        raise pexc.VMPowerOffFailure(reason=emsg,
                                                     lpar_nm=part.name)
                    else:
                        raise pexc.VMPowerOnFailure(reason=emsg,
                                                    lpar_nm=part.name)
            except pexc.JobRequestFailed as error:
                emsg = six.text_type(error)
                LOG.exception(_('Error: %s') % emsg)
                if suffix == _SUFFIX_PARM_POWER_OFF:
                    # If already powered off and not a reboot,
                    # don't send exception
                    if (any(err_prefix in emsg
                            for err_prefix in _ALREADY_POWERED_OFF_ERRS)
                            and not restart):
                        complete = True
                    # If failed for other reasons,
                    # retry with normal vsp power off except for IBM i
                    # where we try immediate osshutdown first
                    elif operation == 'osshutdown':
                        timeout = CONF.pypowervm_job_request_timeout
                        if (part.env == bp.LPARType.OS400
                                and not add_immediate):
                            add_immediate = True
                        else:
                            force_immediate = False
                            normal_vsp_power_off = True
                    # normal vsp power off did not work, try hard vsp power off
                    elif normal_vsp_power_off:
                        timeout = CONF.pypowervm_job_request_timeout
                        force_immediate = True
                        normal_vsp_power_off = False
                    else:
                        raise pexc.VMPowerOffFailure(reason=emsg,
                                                     lpar_nm=part.name)
                else:
                    # If already powered on, don't send exception
                    if (any(err_prefix in emsg
                            for err_prefix in _ALREADY_POWERED_ON_ERRS)):
                        complete = True
                    else:
                        raise pexc.VMPowerOnFailure(reason=emsg,
                                                    lpar_nm=part.name)

    # Invalidate the LPARentry in the adapter cache so the consumers get
    # the current LPAR state by forcing a subsequent read. Feeds must be
    # invalidated too, since the adapter will use them if an entry is not in
    # the cache.
    finally:
        try:
            adapter.invalidate_cache_elem(ms.System.schema_type,
                                          root_id=host_uuid,
                                          child_type=part.schema_type,
                                          child_id=uuid,
                                          invalidate_feeds=True)
        except Exception as e:
            LOG.exception(
                _('Error invalidating adapter cache for LPAR '
                  ' %(lpar_name) with UUID %(lpar_uuid)s: %(exc)s') % {
                      'lpar_name': part.name,
                      'lpar_uuid': uuid,
                      'exc': six.text_type(e)
                  })