Esempio n. 1
0
    def test_set_admin_password_silently_fails(self, mock_exchange,
                                               mock_add_fault):
        error = exception.AgentTimeout(method="fake")
        mock_exchange.side_effect = error
        agent_inst = self._create_agent(None)

        agent_inst.set_admin_password("new_pass")

        mock_add_fault.assert_called_once_with(error, mock.ANY)
Esempio n. 2
0
def _wait_for_new_dom_id(session, vm_ref, old_dom_id, method):
    expiration = time.time() + CONF.xenserver.agent_timeout
    while True:
        dom_id = session.VM.get_domid(vm_ref)

        if dom_id and dom_id != "-1" and dom_id != old_dom_id:
            LOG.debug("Found new dom_id %s", dom_id)
            return

        if time.time() > expiration:
            LOG.debug("Timed out waiting for new dom_id %s", dom_id)
            raise exception.AgentTimeout(method=method.__name__)

        time.sleep(1)
Esempio n. 3
0
def _call_agent(session,
                instance,
                vm_ref,
                method,
                addl_args=None,
                timeout=None,
                success_codes=None):
    """Abstracts out the interaction with the agent xenapi plugin."""
    if addl_args is None:
        addl_args = {}
    if timeout is None:
        timeout = CONF.xenserver.agent_timeout
    if success_codes is None:
        success_codes = ['0']

    # always fetch domid because VM may have rebooted
    dom_id = session.VM.get_domid(vm_ref)
    uuid = uuidutils.generate_uuid()
    args = {
        'id': uuid,
        'dom_id': str(dom_id),
        'timeout': str(timeout),
    }

    try:
        ret = method(session, uuid, dom_id, timeout, **addl_args)
    except XenAPI.Failure as e:
        err_msg = e.details[-1].splitlines()[-1]
        if 'TIMEOUT:' in err_msg:
            LOG.error(
                'TIMEOUT: The call to %(method)s timed out. '
                'args=%(args)r', {
                    'method': method,
                    'args': args
                },
                instance=instance)
            raise exception.AgentTimeout(method=method.__name__)
        elif 'REBOOT:' in err_msg:
            LOG.debug(
                'REBOOT: The call to %(method)s detected a reboot. '
                'args=%(args)r', {
                    'method': method,
                    'args': args
                },
                instance=instance)
            _wait_for_new_dom_id(session, vm_ref, dom_id, method)
            return _call_agent(session, instance, vm_ref, method, addl_args,
                               timeout, success_codes)
        elif 'NOT IMPLEMENTED:' in err_msg:
            LOG.error(
                'NOT IMPLEMENTED: The call to %(method)s is not '
                'supported by the agent. args=%(args)r', {
                    'method': method,
                    'args': args
                },
                instance=instance)
            raise exception.AgentNotImplemented(method=method.__name__)
        else:
            LOG.error(
                'The call to %(method)s returned an error: %(e)s. '
                'args=%(args)r', {
                    'method': method,
                    'args': args,
                    'e': e
                },
                instance=instance)
            raise exception.AgentError(method=method.__name__)

    if not isinstance(ret, dict):
        try:
            ret = jsonutils.loads(ret)
        except TypeError:
            LOG.error(
                'The agent call to %(method)s returned an invalid '
                'response: %(ret)r. args=%(args)r', {
                    'method': method,
                    'ret': ret,
                    'args': args
                },
                instance=instance)
            raise exception.AgentError(method=method.__name__)

    if ret['returncode'] not in success_codes:
        LOG.error(
            'The agent call to %(method)s returned '
            'an error: %(ret)r. args=%(args)r', {
                'method': method,
                'ret': ret,
                'args': args
            },
            instance=instance)
        raise exception.AgentError(method=method.__name__)

    LOG.debug(
        'The agent call to %(method)s was successful: '
        '%(ret)r. args=%(args)r', {
            'method': method,
            'ret': ret,
            'args': args
        },
        instance=instance)

    # Some old versions of the Windows agent have a trailing \\r\\n
    # (ie CRLF escaped) for some reason. Strip that off.
    return ret['message'].replace('\\r\\n', '')
Esempio n. 4
0
def _call_agent(session,
                instance,
                vm_ref,
                method,
                addl_args=None,
                timeout=None,
                success_codes=None):
    """Abstracts out the interaction with the agent xenapi plugin."""
    if addl_args is None:
        addl_args = {}
    if timeout is None:
        timeout = CONF.xenserver.agent_timeout
    if success_codes is None:
        success_codes = ['0']

    vm_rec = session.call_xenapi("VM.get_record", vm_ref)

    args = {
        'id': str(uuid.uuid4()),
        'dom_id': vm_rec['domid'],
        'timeout': str(timeout),
    }
    args.update(addl_args)

    try:
        ret = session.call_plugin('agent', method, args)
    except session.XenAPI.Failure as e:
        err_msg = e.details[-1].splitlines()[-1]
        if 'TIMEOUT:' in err_msg:
            LOG.error(_('TIMEOUT: The call to %(method)s timed out. '
                        'args=%(args)r'), {
                            'method': method,
                            'args': args
                        },
                      instance=instance)
            raise exception.AgentTimeout(method=method)
        elif 'NOT IMPLEMENTED:' in err_msg:
            LOG.error(_('NOT IMPLEMENTED: The call to %(method)s is not '
                        'supported by the agent. args=%(args)r'), {
                            'method': method,
                            'args': args
                        },
                      instance=instance)
            raise exception.AgentNotImplemented(method=method)
        else:
            LOG.error(_('The call to %(method)s returned an error: %(e)s. '
                        'args=%(args)r'), {
                            'method': method,
                            'args': args,
                            'e': e
                        },
                      instance=instance)
            raise exception.AgentError(method=method)

    if not isinstance(ret, dict):
        try:
            ret = jsonutils.loads(ret)
        except TypeError:
            LOG.error(_('The agent call to %(method)s returned an invalid '
                        'response: %(ret)r. args=%(args)r'), {
                            'method': method,
                            'ret': ret,
                            'args': args
                        },
                      instance=instance)
            raise exception.AgentError(method=method)

    if ret['returncode'] not in success_codes:
        LOG.error(_('The agent call to %(method)s returned an '
                    'an error: %(ret)r. args=%(args)r'), {
                        'method': method,
                        'ret': ret,
                        'args': args
                    },
                  instance=instance)
        raise exception.AgentError(method=method)

    LOG.debug(_('The agent call to %(method)s was successful: '
                '%(ret)r. args=%(args)r'), {
                    'method': method,
                    'ret': ret,
                    'args': args
                },
              instance=instance)

    # Some old versions of the Windows agent have a trailing \\r\\n
    # (ie CRLF escaped) for some reason. Strip that off.
    return ret['message'].replace('\\r\\n', '')