예제 #1
0
    def test_pwroff_new_opts(self):
        """Test power_off where add_parms is PowerOffOpts (not legacy)."""
        part = self.mock_partition()

        # VSP hard
        self.run_job.side_effect = self.validate_run(
            part, ex_parms={'operation=shutdown', 'immediate=true'})
        power.power_off(part, None, add_parms=popts.PowerOffOpts().vsp_hard())
        self.assertEqual(1, self.run_job.call_count)

        self.run_job.reset_mock()

        # VSP normal
        self.run_job.side_effect = self.validate_run(
            part, ex_parms={'operation=shutdown'})
        power.power_off(part,
                        None,
                        add_parms=popts.PowerOffOpts().vsp_normal())

        self.run_job.reset_mock()

        # OS immediate
        self.run_job.side_effect = self.validate_run(
            part, ex_parms={'operation=osshutdown', 'immediate=true'})
        power.power_off(part,
                        None,
                        add_parms=popts.PowerOffOpts().os_immediate())

        self.run_job.reset_mock()

        # OS normal
        self.run_job.side_effect = self.validate_run(
            part, ex_parms={'operation=osshutdown'})
        power.power_off(part, None, add_parms=popts.PowerOffOpts().os_normal())
예제 #2
0
    def test_pwrop_stop(self):
        """Test PowerOp.stop."""
        # If RMC is down, VSP normal - make sure the 'immediate' flag goes away
        part = self.mock_partition(rmc_state=pvm_bp.RMCState.INACTIVE)
        self.run_job.side_effect = self.validate_run(
            part, ex_parms={'operation=shutdown'})
        power.PowerOp.stop(
            part, opts=popts.PowerOffOpts().immediate().soft_detect(part))
        self.assertEqual(1, self.run_job.call_count)

        self.run_job.reset_mock()

        # Default parameters - the method figures out whether to do OS shutdown
        part = self.mock_partition()
        self.run_job.side_effect = self.validate_run(
            part, ex_parms={'operation=osshutdown', 'immediate=true'})
        power.PowerOp.stop(
            part, opts=popts.PowerOffOpts().immediate().soft_detect(part))
        self.assertEqual(1, self.run_job.call_count)

        self.run_job.reset_mock()

        # Non-default optional params ignored, timeout
        self.run_job.side_effect = self.validate_run(
            part,
            ex_parms={
                'operation=osshutdown', 'immediate=true', 'restart=true'
            },
            ex_timeout=100,
            ex_synch=False,
            result=self.etimeout())
        self.assertRaises(pexc.VMPowerOffTimeout,
                          power.PowerOp.stop,
                          part,
                          opts=popts.PowerOffOpts(legacy_add_parms={
                              'one': 1,
                              'foo': 'bar'
                          }).os_immediate().restart(),
                          timeout=100,
                          synchronous=False)
        self.assertEqual(1, self.run_job.call_count)

        self.run_job.reset_mock()

        # VSP normal, fail
        self.run_job.side_effect = self.validate_run(
            part, ex_parms={'operation=shutdown'}, result=self.efail())
        self.assertRaises(pexc.VMPowerOffFailure,
                          power.PowerOp.stop,
                          part,
                          opts=popts.PowerOffOpts().vsp_normal())
        self.assertEqual(1, self.run_job.call_count)
예제 #3
0
파일: vm.py 프로젝트: kstev/nova-1
def reboot(adapter, instance, hard):
    """Reboots a VM.

    :param adapter: A pypowervm.adapter.Adapter.
    :param instance: The nova instance to reboot.
    :param hard: Boolean True if hard reboot, False otherwise.
    :raises: InstanceRebootFailure
    """
    # Synchronize power-on and power-off ops on a given instance
    with lockutils.lock('power_%s' % instance.uuid):
        try:
            entry = get_instance_wrapper(adapter, instance)
            if entry.state != pvm_bp.LPARState.NOT_ACTIVATED:
                if hard:
                    power.PowerOp.stop(
                        entry, opts=popts.PowerOffOpts().vsp_hard().restart())
                else:
                    power.power_off_progressive(entry, restart=True)
            else:
                # pypowervm does NOT throw an exception if "already down".
                # Any other exception from pypowervm is a legitimate failure;
                # let it raise up.
                # If we get here, pypowervm thinks the instance is down.
                power.power_on(entry, None)
        except pvm_exc.Error as e:
            LOG.exception("PowerVM error during reboot.", instance=instance)
            raise exc.InstanceRebootFailure(reason=six.text_type(e))
예제 #4
0
 def test_pwrop_stop_no_rmc(self):
     """Test PowerOp.stop with bad RMC state."""
     part = self.mock_partition(rmc_state=pvm_bp.RMCState.INACTIVE)
     self.assertRaises(pexc.OSShutdownNoRMC,
                       power.PowerOp.stop,
                       part,
                       opts=popts.PowerOffOpts().os_normal())
     self.run_job.assert_not_called()
예제 #5
0
def _pwroff_soft_standard_flow(part, restart, timeout):
    """Normal (non-hard) power-off retry flow for non-IBMi partitions.

    START
    |     +---VMPowerOffTimeout-------------------------------------+
    V     |                                                         V
    ========  VMPowerOffFailure  ==========  VMPowerOffFailure  ============
    OS immed ----   or      ---> VSP normal ----   or      ---> return False
    ========   OSShutdownNoRMC   ==========  VMPowerOffTimeout  ============
          | _________________________/
          |/
       SUCCESS
          V
     ===========
     return True
     ===========

    :param part restart timeout: See power_off.
    :return: True if the power-off succeeded; False otherwise.
    :raise VMPowerOffTimeout: If the last power-off attempt timed out.
    :raise VMPowerOffFailure: If the last power-off attempt failed.
    """
    # For backward compatibility, OS shutdown is always immediate.  We don't
    # let PowerOn decide whether to use OS or VSP; instead we trap
    # OSShutdownNoRMC (which is very quick) so we can keep this progression
    # linear.

    opts = popts.PowerOffOpts().restart(value=restart)
    # ==> OS immediate
    try:
        PowerOp.stop(part, opts=opts.os_immediate(), timeout=timeout)
        return True
    except pexc.VMPowerOffTimeout:
        LOG.warning(
            _("Non-IBMi OS immediate shutdown timed out.  Trying VSP "
              "hard shutdown.  Partition: %s"), part.name)
        return False
    except pexc.VMPowerOffFailure:
        LOG.warning(
            _("Non-IBMi OS immediate shutdown failed.  Trying VSP "
              "normal shutdown.  Partition: %s"), part.name)
        # Fall through to VSP normal, but with default timeout
        timeout = CONF.pypowervm_job_request_timeout
    except pexc.OSShutdownNoRMC as error:
        LOG.warning(error.args[0])
        # Fall through to VSP normal

    # ==> VSP normal
    try:
        PowerOp.stop(part, opts.vsp_normal(), timeout=timeout)
        return True
    except pexc.VMPowerOffFailure:
        LOG.warning("Non-IBMi VSP normal shutdown failed.  Partition: %s",
                    part.name)

    return False
예제 #6
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)
예제 #7
0
def power_off(adapter, instance, force_immediate=False, timeout=None):
    """Powers off a VM.

    :param adapter: A pypowervm.adapter.Adapter.
    :param instance: The nova instance to power off.
    :param force_immediate: (Optional, Default False) Should it be immediately
                            shut down.
    :param timeout: (Optional, Default None) How long to wait for the job
                    to complete.  By default, is None which indicates it should
                    use the default from pypowervm's power off method.
    :return: True if the instance was stopped.  False if it was not in a
             stoppable state.
    :raises: InstancePowerOffFailure
    """
    # Synchronize power-on and power-off ops on a given instance
    with lockutils.lock('power_%s' % instance.uuid):
        entry = get_instance_wrapper(adapter, instance)

        # Get the current state and see if we can stop the VM
        LOG.debug(
            "Power off requested for instance in state %(state)s. Force "
            "Immediate Flag: %(force)s.", {
                'state': entry.state,
                'force': force_immediate
            },
            instance=instance)
        if entry.state in POWERVM_STOPABLE_STATE:
            # Now stop the lpar
            try:
                LOG.debug("Power off executing.", instance=instance)
                kwargs = {'timeout': timeout} if timeout else {}
                if force_immediate:
                    power.PowerOp.stop(entry,
                                       opts=popts.PowerOffOpts().vsp_hard(),
                                       **kwargs)
                else:
                    power.power_off_progressive(entry, **kwargs)
            except Exception as e:
                LOG.exception("Failed to power off instance.",
                              instance=instance)
                raise exception.InstancePowerOffFailure(
                    reason=six.text_type(e))
            return True
        else:
            LOG.debug("Power off not required.", instance=instance)

    return False
예제 #8
0
def _power_off_progressive(part, timeout, restart, ibmi_immed=False):

    # Do the progressive-retry sequence appropriate to the partition type.
    if part.env == bp.LPARType.OS400:
        # The IBMi progression.
        if _pwroff_soft_ibmi_flow(part, restart, ibmi_immed, timeout):
            return
            # Fall through to VSP hard
    else:
        # The non-IBMi progression.
        if _pwroff_soft_standard_flow(part, restart, timeout):
            return
            # Fall through to VSP hard

    # If we got here, force_immediate == ON_FAILURE, so fall back to VSP hard.
    # Let this one finish or raise.
    # ==> VSP hard
    LOG.warning(_("VSP hard shutdown with default timeout.  Partition: %s"),
                part.name)
    PowerOp.stop(part, popts.PowerOffOpts().vsp_hard().restart(value=restart))
예제 #9
0
 def test_power_off_opts(self):
     # Can OS shutdown?
     ltyp = bp.LPARType
     rmcs = bp.RMCState
     for env, rmc, exp in ((ltyp.AIXLINUX, rmcs.ACTIVE, True),
                           (ltyp.AIXLINUX, rmcs.BUSY, False),
                           (ltyp.AIXLINUX, rmcs.INACTIVE, False),
                           (ltyp.OS400, rmcs.ACTIVE, True),
                           (ltyp.OS400, rmcs.BUSY, True),
                           (ltyp.OS400, rmcs.INACTIVE, True),
                           (ltyp.VIOS, rmcs.ACTIVE, True),
                           (ltyp.VIOS, rmcs.BUSY, False),
                           (ltyp.VIOS, rmcs.INACTIVE, False)):
         self.assertEqual(exp, popts.PowerOffOpts.can_os_shutdown(
             mock.Mock(env=env, rmc_state=rmc)))
     # Default init
     poo = popts.PowerOffOpts()
     self.assertEqual('PowerOff()', str(poo))
     self.assertEqual('PowerOff', poo.JOB_SUFFIX)
     self.assertFalse(poo.is_param_set(popts.PowerOffOperation.KEY))
     # Legacy add_parms init.  Unknown keys are ignored.
     poo = popts.PowerOffOpts(
         legacy_add_parms=dict(operation='shutdown', foo=1, restart='true',
                               bar=2, immediate='true'))
     self.assertEqual(
         'PowerOff(immediate=true, operation=shutdown, restart=true)',
         str(poo))
     self.assertTrue(poo.is_immediate)
     self.assertTrue(poo.is_restart)
     self.assertFalse(poo.is_os)
     self.assertTrue(poo.is_param_set(popts.PowerOffOperation.KEY))
     # Now an "empty" one
     poo = popts.PowerOffOpts(legacy_add_parms=dict(foo=1, bar=2))
     self.assertEqual('PowerOff()', str(poo))
     self.assertFalse(poo.is_immediate)
     self.assertFalse(poo.is_restart)
     self.assertFalse(poo.is_os)
     self.assertFalse(poo.is_param_set(popts.PowerOffOperation.KEY))
     # Immediate
     self.assertIs(poo, poo.immediate())
     self.assertEqual('PowerOff(immediate=true)', str(poo))
     self.assertTrue(poo.is_immediate)
     self.assertFalse(poo.is_restart)
     self.assertFalse(poo.is_os)
     self.assertFalse(poo.is_param_set(popts.PowerOffOperation.KEY))
     # Restart
     self.assertIs(poo, poo.restart())
     self.assertEqual(
         'PowerOff(immediate=true, restart=true)', str(poo))
     self.assertTrue(poo.is_immediate)
     self.assertTrue(poo.is_restart)
     self.assertFalse(poo.is_os)
     self.assertFalse(poo.is_param_set(popts.PowerOffOperation.KEY))
     # Operation
     self.assertIs(poo, poo.operation(popts.PowerOffOperation.DUMPRESTART))
     self.assertEqual(
         'PowerOff(immediate=true, operation=dumprestart, restart=true)',
         str(poo))
     self.assertTrue(poo.is_immediate)
     self.assertTrue(poo.is_restart)
     self.assertFalse(poo.is_os)
     self.assertTrue(poo.is_param_set(popts.PowerOffOperation.KEY))
     # OS shutdown
     self.assertIs(poo, poo.operation(popts.PowerOffOperation.OS))
     self.assertEqual(
         'PowerOff(immediate=true, operation=osshutdown, restart=true)',
         str(poo))
     self.assertTrue(poo.is_immediate)
     self.assertTrue(poo.is_restart)
     self.assertTrue(poo.is_os)
     self.assertTrue(poo.is_param_set(popts.PowerOffOperation.KEY))
     # Booleans can be shut off
     self.assertIs(poo, poo.immediate(value=False))
     self.assertEqual('PowerOff(operation=osshutdown, restart=true)',
                      str(poo))
     self.assertFalse(poo.is_immediate)
     self.assertTrue(poo.is_restart)
     self.assertTrue(poo.is_os)
     self.assertIs(poo, poo.restart(value=False))
     self.assertEqual('PowerOff(operation=osshutdown)', str(poo))
     self.assertFalse(poo.is_immediate)
     self.assertFalse(poo.is_restart)
     self.assertTrue(poo.is_os)
     # "Smart" methods.  Make sure restart is preserved every time we change
     poo.restart()
     # OS immediate
     self.assertIs(poo, poo.os_immediate())
     self.assertEqual('PowerOff(immediate=true, operation=osshutdown, '
                      'restart=true)', str(poo))
     self.assertTrue(poo.is_immediate)
     self.assertTrue(poo.is_restart)
     self.assertTrue(poo.is_os)
     self.assertTrue(poo.is_param_set(popts.PowerOffOperation.KEY))
     # OS normal (wipes out immediate)
     self.assertIs(poo, poo.os_normal())
     self.assertEqual('PowerOff(operation=osshutdown, restart=true)',
                      str(poo))
     self.assertFalse(poo.is_immediate)
     self.assertTrue(poo.is_restart)
     self.assertTrue(poo.is_os)
     self.assertTrue(poo.is_param_set(popts.PowerOffOperation.KEY))
     # VSP hard
     self.assertIs(poo, poo.vsp_hard())
     self.assertEqual('PowerOff(immediate=true, operation=shutdown, '
                      'restart=true)', str(poo))
     self.assertTrue(poo.is_immediate)
     self.assertTrue(poo.is_restart)
     self.assertFalse(poo.is_os)
     self.assertTrue(poo.is_param_set(popts.PowerOffOperation.KEY))
     # VSP normal (wipes out immediate)
     self.assertIs(poo, poo.vsp_normal())
     self.assertEqual('PowerOff(operation=shutdown, restart=true)',
                      str(poo))
     self.assertFalse(poo.is_immediate)
     self.assertTrue(poo.is_restart)
     self.assertFalse(poo.is_os)
     self.assertTrue(poo.is_param_set(popts.PowerOffOperation.KEY))
     # Soft detect
     part = mock.Mock(env=ltyp.AIXLINUX, rmc_state=rmcs.ACTIVE)
     self.assertIs(poo, poo.soft_detect(part))
     self.assertTrue(poo.is_os)
     self.assertTrue(poo.is_immediate)
     self.assertTrue(poo.is_restart)
     self.assertTrue(poo.is_param_set(popts.PowerOffOperation.KEY))
     # Explicit normal shutdown
     self.assertIs(poo, poo.soft_detect(part, immed_if_os=False))
     self.assertTrue(poo.is_os)
     self.assertFalse(poo.is_immediate)
     self.assertTrue(poo.is_restart)
     self.assertTrue(poo.is_param_set(popts.PowerOffOperation.KEY))
     # Explicit immediate OS shutdown
     self.assertIs(poo, poo.soft_detect(part, immed_if_os=True))
     self.assertTrue(poo.is_os)
     self.assertTrue(poo.is_immediate)
     self.assertTrue(poo.is_restart)
     self.assertTrue(poo.is_param_set(popts.PowerOffOperation.KEY))
     # Can't OS shutdown
     part = mock.Mock(env=ltyp.VIOS, rmc_state=rmcs.BUSY)
     self.assertIs(poo, poo.soft_detect(part))
     self.assertFalse(poo.is_os)
     self.assertFalse(poo.is_immediate)
     self.assertTrue(poo.is_restart)
     self.assertTrue(poo.is_param_set(popts.PowerOffOperation.KEY))
     # immed_if_os ignored
     self.assertIs(poo, poo.soft_detect(part, immed_if_os=True))
     self.assertFalse(poo.is_os)
     self.assertFalse(poo.is_immediate)
     self.assertTrue(poo.is_restart)
     self.assertIs(poo, poo.soft_detect(part, immed_if_os=False))
     self.assertFalse(poo.is_os)
     self.assertFalse(poo.is_immediate)
     self.assertTrue(poo.is_restart)
     self.assertEqual('PowerOff(operation=shutdown, restart=true)',
                      str(poo))
     self.assertTrue(poo.is_param_set(popts.PowerOffOperation.KEY))
     # IBMi defaults to OS normal
     part = mock.Mock(env=ltyp.OS400, rmc_state=rmcs.INACTIVE)
     self.assertIs(poo, poo.soft_detect(part))
     self.assertTrue(poo.is_os)
     self.assertFalse(poo.is_immediate)
     self.assertTrue(poo.is_restart)
     self.assertTrue(poo.is_param_set(popts.PowerOffOperation.KEY))
     # Explicit immediate
     self.assertIs(poo, poo.soft_detect(part, immed_if_os=True))
     self.assertTrue(poo.is_os)
     self.assertTrue(poo.is_immediate)
     self.assertTrue(poo.is_restart)
     self.assertTrue(poo.is_param_set(popts.PowerOffOperation.KEY))
예제 #10
0
def _pwroff_soft_ibmi_flow(part, restart, immediate, timeout):
    """Normal (non-hard) power-off retry flow for IBMi partitions.

          ==================
          opts.is_immediate? <--START
          ==================
           |             |
           NO           YES
           V             V
    =========          ============          ==========          ============
    OS normal -FAIL*-> OS immediate -FAIL*-> VSP normal -FAIL*-> return False
    =========          ============          ==========          ============
        |_________________ | ___________________|
                          |||
                        SUCCESS
                           V         *VMPowerOffTimeout OR
                      ===========     VMPowerOffFailure
                      return True
                      ===========

    :param part restart timeout: See power_off.
    :param immediate: Boolean.  Indicates whether to try os-normal first
                      (False, the default) before progressing to os-immediate.
                      If True, skip trying os-normal shutdown.
    :return: True if the power-off succeeded; False otherwise.
    :raise VMPowerOffTimeout: If the last power-off attempt timed out.
    :raise VMPowerOffFailure: If the last power-off attempt failed.
    """
    opts = popts.PowerOffOpts().restart(value=restart)
    # If immediate was already specified, skip OS-normal.
    if not immediate:
        # ==> OS normal
        try:
            PowerOp.stop(part, opts=opts.os_normal(), timeout=timeout)
            return True
        except pexc.VMPowerOffFailure:
            LOG.warning(
                _("IBMi OS normal shutdown failed.  Trying OS "
                  "immediate shutdown.  Partition: %s"), part.name)
            # Fall through to OS immediate, with default timeout
            timeout = CONF.pypowervm_job_request_timeout

    # ==> OS immediate
    try:
        PowerOp.stop(part, opts=opts.os_immediate(), timeout=timeout)
        return True
    except pexc.VMPowerOffFailure:
        LOG.warning(
            _("IBMi OS immediate shutdown failed.  Trying VSP normal "
              "shutdown.  Partition: %s"), part.name)
        # Fall through to VSP normal

    # ==> VSP normal
    try:
        PowerOp.stop(part, opts=opts.vsp_normal(), timeout=timeout)
        return True
    except pexc.VMPowerOffFailure:
        LOG.warning("IBMi VSP normal shutdown failed.  Partition: %s",
                    part.name)

    return False