Exemple #1
0
def _ovs_vsctl(args):
    full_args = ['ovs-vsctl', '--timeout=%s' % CONF.ovs_vsctl_timeout] + args
    try:
        return utils.execute(*full_args)
    except Exception as e:
        LOG.error(_LE("Unable to execute %(cmd)s. Exception: %(exception)s"),
                  {'cmd': full_args, 'exception': e})
        raise exception.AgentError(method=full_args)
Exemple #2
0
    def test_call_agent_swallows_error(self, mock_call_agent,
                                       mock_add_instance_fault):
        fake_error = exception.AgentError(method="bob")
        mock_call_agent.side_effect = fake_error

        instance = _get_fake_instance()
        agent = self._create_agent(instance)

        agent._call_agent("bob")

        mock_call_agent.assert_called_once_with(agent.session, agent.instance,
                agent.vm_ref, "bob", None, None, None)
        mock_add_instance_fault.assert_called_once_with(fake_error, mock.ANY)
Exemple #3
0
    def test_call_agent_throws_error(self, mock_call_agent,
                                     mock_add_instance_fault):
        fake_error = exception.AgentError(method="bob")
        mock_call_agent.side_effect = fake_error

        instance = _get_fake_instance()
        agent = self._create_agent(instance)

        self.assertRaises(exception.AgentError, agent._call_agent,
                          "bob", ignore_errors=False)

        mock_call_agent.assert_called_once_with(agent.session, agent.instance,
                agent.vm_ref, "bob", None, None, None)
        self.assertFalse(mock_add_instance_fault.called)
Exemple #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']

    # 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', '')
Exemple #5
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', '')