def test_command_chain(): chain = CommandChain('test') chain.add_execute(['cmd2']) chain.add_copy('/local', '/remote') chain.prepend_command(['cmd1']) chain.add_execute(['cmd3']) assert chain.get_commands() == [('execute', ['cmd1'], None, None), ('execute', ['cmd2'], None, None), ('copy', '/local', '/remote', False, False, None), ('execute', ['cmd3'], None, None)]
def test_command_chain(): chain = CommandChain('test') chain.add_execute(['cmd2']) chain.add_copy('/local', '/remote') chain.prepend_command(['cmd1']) chain.add_execute(['cmd3']) assert chain.get_commands() == [ ('execute', ['cmd1'], None, None), ('execute', ['cmd2'], None, None), ('copy', '/local', '/remote', False, False, None), ('execute', ['cmd3'], None, None) ]
def _run_chain_command(self, chain: CommandChain, host, chain_result): # Prepare status json if self.async_delegate is not None: log.debug('Preparing a status json') self.async_delegate.prepare_status(chain.namespace, self.__targets) host_status = 'hosts_success' host_port = '{}:{}'.format(host.ip, host.port) command_map = { CommandChain.execute_flag: self.run_async, CommandChain.copy_flag: self.copy_async } process_exit_code_map = { None: { 'host_status': 'terminated', 'host_status_count': 'hosts_terminated' }, 0: { 'host_status': 'success', 'host_status_count': 'hosts_success' }, 'failed': { 'host_status': 'failed', 'host_status_count': 'hosts_failed' } } for command in chain.get_commands(): stage = command[-1] if stage is not None: # a stage can be a function which takes a Node() object and does evaluation if callable(stage): stage = stage(host) log.debug('{}: {}'.format(host_port, stage)) future = asyncio.Future() if self.async_delegate is not None: log.debug('Using async_delegate with callback') callback_called = asyncio.Future() future.add_done_callback(lambda future: self.async_delegate.on_update(future, callback_called)) # command[0] is a type of a command, could be CommandChain.execute_flag, CommandChain.copy_flag result = yield from command_map.get(command[0], None)(host, command, chain.namespace, future, stage) status = process_exit_code_map.get(result[host_port]['returncode'], process_exit_code_map['failed']) host_status = status['host_status'] if self.async_delegate is not None: # We need to make sure the callback was executed before we can proceed further # 5 seconds should be enough for a callback. try: yield from asyncio.wait_for(callback_called, 5) except asyncio.TimeoutError: log.error('Callback did not execute within 5 sec') host_status = 'terminated' break _, result, host_object = future.result() chain_result.append(result) if host_status != 'success': break if self.async_delegate is not None: # Update chain status. self.async_delegate.on_done(chain.namespace, result, host_status=host_status)
def _run_chain_command(self, chain: CommandChain, host, chain_result): # Prepare status json if self.async_delegate is not None: log.debug('Preparing a status json') self.async_delegate.prepare_status(chain.namespace, self.__targets) host_status = 'hosts_success' host_port = '{}:{}'.format(host.ip, host.port) command_map = { CommandChain.execute_flag: self.run_async, CommandChain.copy_flag: self.copy_async } process_exit_code_map = { None: { 'host_status': 'terminated', 'host_status_count': 'hosts_terminated' }, 0: { 'host_status': 'success', 'host_status_count': 'hosts_success' }, 'failed': { 'host_status': 'failed', 'host_status_count': 'hosts_failed' } } for command in chain.get_commands(): stage = command[-1] if stage is not None: # a stage can be a function which takes a Node() object and does evaluation if callable(stage): stage = stage(host) log.debug('{}: {}'.format(host_port, stage)) future = asyncio.Future() if self.async_delegate is not None: log.debug('Using async_delegate with callback') callback_called = asyncio.Future() future.add_done_callback(lambda future: self.async_delegate. on_update(future, callback_called)) # command[0] is a type of a command, could be CommandChain.execute_flag, CommandChain.copy_flag result = yield from command_map.get(command[0], None)(host, command, chain.namespace, future, stage) status = process_exit_code_map.get(result[host_port]['returncode'], process_exit_code_map['failed']) host_status = status['host_status'] if self.async_delegate is not None: # We need to make sure the callback was executed before we can proceed further # 5 seconds should be enough for a callback. try: yield from asyncio.wait_for(callback_called, 5) except asyncio.TimeoutError: log.error('Callback did not execute within 5 sec') host_status = 'terminated' break _, result, host_object = future.result() chain_result.append(result) if host_status != 'success': break if self.async_delegate is not None: # Update chain status. self.async_delegate.on_done(chain.namespace, result, host_status=host_status)