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)
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)
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)
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', '')
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', '')