Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
    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)
Пример #4
0
    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)
Пример #5
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_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
Пример #6
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
Пример #7
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_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