def test_run_direct_failure(self): """ Test that ActionPluginManager.run re-raises exceptions """ with self.assertRaises(AssertionError): ActionPluginManager().run('action_one_no_context', None, {'arg1': "the_wrong_thing"})
def main(): """handle unexpected exceptions""" parser = argparse.ArgumentParser( description="Integrated Manager for Lustre software Agent") parser.add_argument("--publish-zconf", action="store_true") parser.parse_args() signal.signal(signal.SIGHUP, signal.SIG_IGN) daemon_log_setup() console_log_setup() daemon_log.info("Starting") try: daemon_log.info("Entering main loop") try: url = urljoin(os.environ["IML_MANAGER_URL"], "agent/message/") except KeyError as e: daemon_log.error( "No configuration found (must be registered before running the agent service), " "details: %s" % e) return if config.profile_managed is False: # This is kind of terrible. The design of DevicePluginManager is # such that it can be called with either class methods or # instantiated and then called with instance methods. As such, # we can't pass in a list of excluded plugins to the instance # constructor. Well, we could, but it would only work some # of the time and that would be even more awful. import chroma_agent.plugin_manager chroma_agent.plugin_manager.EXCLUDED_PLUGINS += ['corosync'] agent_client = AgentClient(url, ActionPluginManager(), DevicePluginManager(), ServerProperties(), Crypto(ENV_PATH)) def teardown_callback(*args, **kwargs): agent_client.stop() agent_client.join() [function() for function in agent_daemon_teardown_functions] signal.signal(signal.SIGINT, teardown_callback) signal.signal(signal.SIGTERM, teardown_callback) signal.signal(signal.SIGUSR1, decrease_loglevel) signal.signal(signal.SIGUSR2, increase_loglevel) # Call any agent daemon startup methods that were registered. [function() for function in agent_daemon_startup_functions] agent_client.start() # Waking-wait to pick up signals while not agent_client.stopped.is_set(): agent_client.stopped.wait(timeout=10) agent_client.join() except Exception, e: backtrace = '\n'.join(traceback.format_exception(*(sys.exc_info()))) daemon_log.error("Unhandled exception: %s" % backtrace)
def reregister_server(url, address): """ Update manager url and register agent address with manager """ if _service_is_running() is True: console_log.warning( "chroma-agent service was running before registration, stopping.") agent_service.stop() config.set('settings', 'server', {'url': url}) crypto = Crypto(config.path) agent_client = AgentClient(url + 'reregister/', ActionPluginManager(), DevicePluginManager(), ServerProperties(), crypto) data = {'address': address, 'fqdn': agent_client._fqdn} try: result = agent_client.post(data) except HttpError: console_log.error("Reregistration failed to %s with request %s" % (agent_client.url, data)) raise console_log.info("Starting chroma-agent service") agent_service.start() return result
def register_server(url, ca, secret, address=None): if _service_is_running() is True: console_log.warning( "chroma-agent service was running before registration, stopping.") agent_service.stop() crypto = Crypto(config.path) # Call delete in case we are over-writing a previous configuration that wasn't removed properly crypto.delete() crypto.install_authority(ca) agent_client = AgentClient(url + "register/%s/" % secret, ActionPluginManager(), DevicePluginManager(), ServerProperties(), crypto) registration_result = agent_client.register(address) crypto.install_certificate(registration_result['certificate']) config.set('settings', 'server', {'url': url}) console_log.info("Enabling chroma-agent service") agent_service.enable() console_log.info("Starting chroma-agent service") agent_service.start() return registration_result
def main(): configure_logging() parser = argparse.ArgumentParser( description="Intel Manager for Lustre Agent") subparsers = parser.add_subparsers() for command, fn in ActionPluginManager().commands.items(): _register_function(subparsers, command, fn) try: AgentShell.thread_state.enable_save() args = parser.parse_args() result = args.func(args) try: print result['raw_result'] except (TypeError, KeyError): sys.stderr.write( json.dumps(AgentShell.thread_state.get_subprocesses(), indent=2)) sys.stderr.write("\n\n") print json.dumps({'success': True, 'result': result}, indent=2) except SystemExit: raise except Exception: exc_info = sys.exc_info() backtrace = '\n'.join( traceback.format_exception(*(exc_info or sys.exc_info()))) sys.stderr.write("%s\n" % backtrace) sys.stderr.write( json.dumps(AgentShell.thread_state.get_subprocesses(), indent=2)) sys.stderr.write("\n\n") print json.dumps({'success': False, 'backtrace': backtrace}, indent=2)
def reregister_server(url, address): """ Update manager url and register agent address with manager """ if _service_is_running() is True: console_log.warning( "chroma-agent service was running before registration, stopping.") agent_service.stop() conf.set_server_url(url) crypto = Crypto(conf.ENV_PATH) agent_client = AgentClient( url + "reregister/", ActionPluginManager(), DevicePluginManager(), ServerProperties(), crypto, ) data = {"address": address, "fqdn": agent_client._fqdn} try: result = agent_client.post(data) except HttpError: console_log.error("Reregistration failed to %s with request %s" % (agent_client.url, data)) raise console_log.info("Starting chroma-agent service") agent_service.start() return result
def test_run_direct_success(self): """ Test that we can run an action directly using ActionPluginManager as the CLI would. """ result = ActionPluginManager().run('action_one_no_context', None, {'arg1': "arg1_test"}) self.assertEqual(result, ACTION_ONE_NO_CONTEXT_RETVAL)
def test_run_direct_success_with_context(self): """ Test that we can run an action using ActionPluginManager as the daemon would. """ result = ActionPluginManager().run('action_one_with_context', AgentDaemonContext([]), {'arg1': "arg1_test"}) self.assertEqual(result, ACTION_ONE_WITH_CONTEXT_RETVAL)
def setUp(self): # Register some testing actions self.action_plugins = ActionPluginManager() for action in ACTIONS: self.action_plugins.commands[action.__name__] = action # Intercept messages sent with a thread safe mock mock.patch('chroma_agent.plugin_manager.DevicePlugin.send_message', self.mock_send_message).start() self.mock_send_message_lock = threading.Lock() self.mock_send_message_call_count = 0 self.mock_send_message_call_args_list = [] # Intercept subprocess invocations if self.MOCK_SUBPROCESSES: mock.patch('iml_common.lib.shell.BaseShell._run', self.mock_run).start() # Guaranteed cleanup with unittest2 self.addCleanup(mock.patch.stopall)
def test_get_action_plugins(self): """Test that we get a list of loaded plugin classes.""" self.assertNotEqual(len(ActionPluginManager().commands), 0)
"No configuration found (must be registered before running the agent service), " "details: %s" % e) return if config.profile_managed is False: # This is kind of terrible. The design of DevicePluginManager is # such that it can be called with either class methods or # instantiated and then called with instance methods. As such, # we can't pass in a list of excluded plugins to the instance # constructor. Well, we could, but it would only work some # of the time and that would be even more awful. import chroma_agent.plugin_manager chroma_agent.plugin_manager.EXCLUDED_PLUGINS += ['corosync'] agent_client = AgentClient(conf['url'] + "message/", ActionPluginManager(), DevicePluginManager(), ServerProperties(), Crypto(config.path)) def teardown_callback(*args, **kwargs): agent_client.stop() agent_client.join() [function() for function in agent_daemon_teardown_functions] if not args.foreground: handlers = { signal.SIGTERM: teardown_callback, signal.SIGUSR1: decrease_loglevel, signal.SIGUSR2: increase_loglevel } set_signal_handlers(handlers)