def do_run(self): self.context = RsyncContext( self.options.source, self.options.destination, self.options.__dict__, sys.stdout, sys.stderr ) check_required_command('rsync') hosts = self.check_hosts() rsync_command = 'rsync %s %s %s' % ( self.context.options['rsync_options'], self.context.source, self.context.destination ) color = create_coloring_object(sys.stdout) # prompt when production environment self.confirm_execution_on_production( 'Rsync command "%s" will be executed %s hosts. Are you sure? [yes/NO]: ' % (color.green(rsync_command), color.green(len(hosts))) ) executor = RsyncExecutor(self.context, self.log, hosts) return executor.execute(self.context.source, self.context.destination)
def do_run(self): self.context = CommandContext(self.options.command, self.options.__dict__, sys.stdout, sys.stderr) check_required_command("ssh") hosts = self.check_hosts() color = create_coloring_object(sys.stdout) # prompt when production environment self.confirm_execution_on_production( 'Command "%s" will be executed to %s hosts. Are you sure? [yes/NO]: ' % (color.green(" ".join(self.context.arguments)), color.green(len(hosts))) ) executor = CommandExecutor(self.context, self.log, hosts) return executor.execute(self.context.arguments)
def do_run(self): self.context = CommandContext(self.options.command, self.options.__dict__, sys.stdout, sys.stderr) check_required_command('ssh') hosts = self.check_hosts() color = create_coloring_object(sys.stdout) # prompt when production environment self.confirm_execution_on_production( 'Command "%s" will be executed to %s hosts. Are you sure? [yes/NO]: ' % (color.green(' '.join( self.context.arguments)), color.green(len(hosts)))) executor = CommandExecutor(self.context, self.log, hosts) return executor.execute(self.context.arguments)
def do_run(self): self.context = RsyncContext(self.options.source, self.options.destination, self.options.__dict__, sys.stdout, sys.stderr) check_required_command('rsync') hosts = self.check_hosts() rsync_command = 'rsync %s %s %s' % ( self.context.options['rsync_options'], self.context.source, self.context.destination) color = create_coloring_object(sys.stdout) # prompt when production environment self.confirm_execution_on_production( 'Rsync command "%s" will be executed %s hosts. Are you sure? [yes/NO]: ' % (color.green(rsync_command), color.green(len(hosts)))) executor = RsyncExecutor(self.context, self.log, hosts) return executor.execute(self.context.source, self.context.destination)
def process_async_results( self, async_results, create_output, create_timeout_message, create_timeout_raise_error_message, create_failure_message, create_failure_raise_error_message, create_failure_last_message, ): out, err = self.context.out, self.context.err color = create_coloring_object(out) options = self.context.options hosts_count = len(self.hosts) finished = 0 error_hosts_count = 0 output_format = self.output_format(options.get('output_format', DEFAULT_COMMAND_OUTPUT_FORMAT)) if six.PY2: output_format = output_format.decode(DEFAULT_EXPECT_ENCODING) output_format_template = string.Template(output_format) timeout = options.get('timeout', DEFAULT_TIMEOUT) error_prefix = color.red(color.bold('[error]')) # insert newline for error messages execution_info = {} # Main loop continues until all processes are done while finished < hosts_count: for dict in async_results: host = dict['host'] command = dict['command'] async_result = dict['async_result'] if not async_result.ready(): continue exit_status = 1 command_output = '' timeout_detail = None try: exit_status, command_output = async_result.get(timeout = timeout) self.log.debug("host = %s, exit_status = %d" % (host, exit_status)) except (TimeoutError, multiprocessing.TimeoutError): error = sys.exc_info()[1] timeout_detail = str(error) execution_info[host] = { 'timeout': 1 } async_results.remove(dict) finished += 1 output = create_output(color, output_format_template, command, host, exit_status, command_output) execution_info[host] = { 'exit_status': exit_status, 'command_output': command_output, 'timeout': False, } if command_output == '': # if command_output is empty, chomp last newline character for ugly output output = re.sub(os.linesep + r'\Z', '', output) if exit_status == 0: if six.PY2: output = output.encode(DEFAULT_EXPECT_ENCODING) print_(output, file=out) elif timeout_detail is not None: print_('%s %s\n' % ( error_prefix, create_timeout_message(color, output, timeout) ), file=out) execution_info[host]['timeout'] = True error_hosts_count += 1 if self.raise_error: print_('%s %s\n' % ( error_prefix, create_timeout_raise_error_message(color, command, host, timeout) ), file=err) return 1 else: print_('%s %s\n' % ( error_prefix, create_failure_message(color, output, exit_status) ), file=out) error_hosts_count += 1 if self.raise_error: print_('%s %s' % ( error_prefix, create_failure_raise_error_message(color, command, host) ), file=err) return 1 # Free process pool self.terminate_processes() if error_hosts_count > 0: hosts = '' for h in self.hosts: if execution_info[h]['exit_status'] != 0: hosts += ' %s\n' % (h) hosts = hosts.rstrip() print_('%s %s' % ( error_prefix, create_failure_last_message(color, command, hosts) ), file=err) return 1 if options.get('verify_output'): has_different_output = False prev_output = None hosts = '' for h in self.hosts: output = execution_info[h]['command_output'] self.log.debug("host: '%s', prev_output: '%s', output = '%s'" % (h, prev_output, output)) if prev_output != None and output != prev_output: hosts += ' %s\n' % (h) has_different_output = True prev_output = output hosts = hosts.rstrip() if has_different_output: print_("%s Detected different command output on following hosts.\n%s" \ % (color.red(error_prefix), hosts), file=err) return 3 else: print_(color.green('Verified output of all hosts.'), file=out) return 0
def process_async_results( self, async_results, create_output, create_timeout_message, create_timeout_raise_error_message, create_failure_message, create_failure_raise_error_message, create_failure_last_message, ): out, err = self.context.out, self.context.err color = create_coloring_object(out) options = self.context.options hosts_count = len(self.hosts) finished = 0 error_hosts = {} output_format_template = string.Template(self.output_format(options.get('output_format', DEFAULT_COMMAND_OUTPUT_FORMAT))) timeout = options.get('timeout', DEFAULT_TIMEOUT) error_prefix = color.red(color.bold('[error]')) # Main loop continues until all processes are done while finished < hosts_count: for dict in async_results: host = dict['host'] command = dict['command'] async_result = dict['async_result'] if not async_result.ready(): continue exit_status = 1 command_output = '' timeout_detail = None try: exit_status, command_output = async_result.get(timeout = timeout) self.log.debug("host = %s, exit_status = %d" % (host, exit_status)) except (TimeoutError, multiprocessing.TimeoutError), error: timeout_detail = str(error) async_results.remove(dict) finished += 1 output = create_output(color, output_format_template, command, host, exit_status, command_output) if exit_status == 0: print >> out, output elif timeout_detail is not None: print >> out, "%s %s" % ( error_prefix, create_timeout_message(color, output, timeout) ) error_hosts[host] = 2 if self.raise_error: print >> err, "%s %s" % ( error_prefix, create_timeout_raise_error_message(color, command, host, timeout) ) return 1 else: print >> out, "%s %s" % ( error_prefix, create_failure_message(color, output, exit_status) ) error_hosts[host] = 1 if self.raise_error: print >> err, "%s %s" % ( error_prefix, create_failure_raise_error_message(color, command, host) ) return 1
def process_async_results( self, async_results, create_output, create_timeout_message, create_timeout_raise_error_message, create_failure_message, create_failure_raise_error_message, create_failure_last_message, ): out, err = self.context.out, self.context.err color = create_coloring_object(out) options = self.context.options hosts_count = len(self.hosts) finished = 0 error_hosts_count = 0 output_format_template = string.Template(self.output_format(options.get('output_format', DEFAULT_COMMAND_OUTPUT_FORMAT))) timeout = options.get('timeout', DEFAULT_TIMEOUT) error_prefix = color.red(color.bold('[error]')) # insert newline for error messages execution_info = {} # Main loop continues until all processes are done while finished < hosts_count: for dict in async_results: host = dict['host'] command = dict['command'] async_result = dict['async_result'] if not async_result.ready(): continue exit_status = 1 command_output = '' timeout_detail = None try: exit_status, command_output = async_result.get(timeout = timeout) self.log.debug("host = %s, exit_status = %d" % (host, exit_status)) except (TimeoutError, multiprocessing.TimeoutError): error = sys.exc_info()[1] timeout_detail = str(error) execution_info[host] = { 'timeout': 1 } async_results.remove(dict) finished += 1 output = create_output(color, output_format_template, command, host, exit_status, command_output) execution_info[host] = { 'exit_status': exit_status, 'command_output': command_output, 'timeout': False, } if command_output == '': # if command_output is empty, chomp last newline character for ugly output output = re.sub(os.linesep + r'\Z', '', output) if exit_status == 0: print_(output, file=out) elif timeout_detail is not None: print_('%s %s\n' % ( error_prefix, create_timeout_message(color, output, timeout) ), file=out) execution_info[host]['timeout'] = True error_hosts_count += 1 if self.raise_error: print_('%s %s\n' % ( error_prefix, create_timeout_raise_error_message(color, command, host, timeout) ), file=err) return 1 else: print_('%s %s\n' % ( error_prefix, create_failure_message(color, output, exit_status) ), file=out) error_hosts_count += 1 if self.raise_error: print_('%s %s' % ( error_prefix, create_failure_raise_error_message(color, command, host) ), file=err) return 1 # Free process pool self.terminate_processes() if error_hosts_count > 0: hosts = '' for h in self.hosts: if execution_info[h]['exit_status'] != 0: hosts += ' %s\n' % (h) hosts = hosts.rstrip() print_('%s %s' % ( error_prefix, create_failure_last_message(color, command, hosts) ), file=err) return 1 if options.get('verify_output'): has_different_output = False prev_output = None hosts = '' for h in self.hosts: output = execution_info[h]['command_output'] self.log.debug("host: '%s', prev_output: '%s', output = '%s'" % (h, prev_output, output)) if prev_output != None and output != prev_output: hosts += ' %s\n' % (h) has_different_output = True prev_output = output hosts = hosts.rstrip() if has_different_output: print_("%s Detected different command output on following hosts.\n%s" \ % (color.red(error_prefix), hosts), file=err) return 3 else: print_(color.green('Verified output of all hosts.'), file=out) return 0