From 81e72759fc13b2343fb22ca4db020527cc2af4b6 Mon Sep 17 00:00:00 2001 From: Javier Aranda Date: Mon, 31 Mar 2025 21:08:58 +0200 Subject: [PATCH] Allow to use config object per running --- lib/sshkit/backends/abstract.rb | 14 +++++++++----- lib/sshkit/backends/local.rb | 4 ++-- lib/sshkit/command.rb | 17 +++++++++-------- lib/sshkit/configuration.rb | 8 ++++---- lib/sshkit/coordinator.rb | 15 ++++++--------- lib/sshkit/dsl.rb | 8 ++++---- lib/sshkit/formatters/abstract.rb | 3 ++- lib/sshkit/formatters/pretty.rb | 2 +- lib/sshkit/mapping_interaction_handler.rb | 5 +++-- lib/sshkit/runners/abstract.rb | 11 ++++++----- lib/sshkit/runners/group.rb | 4 ++-- lib/sshkit/runners/sequential.rb | 4 ++-- test/unit/backends/test_abstract.rb | 2 +- test/unit/test_configuration.rb | 2 +- test/unit/test_mapping_interaction_handler.rb | 4 ++-- 15 files changed, 54 insertions(+), 49 deletions(-) diff --git a/lib/sshkit/backends/abstract.rb b/lib/sshkit/backends/abstract.rb index 592f7b08..b6bfe536 100644 --- a/lib/sshkit/backends/abstract.rb +++ b/lib/sshkit/backends/abstract.rb @@ -24,7 +24,7 @@ class Abstract extend Forwardable def_delegators :output, :log, :fatal, :error, :warn, :info, :debug - attr_reader :host + attr_reader :host, :config def run Thread.current["sshkit_backend"] = self @@ -33,10 +33,12 @@ def run Thread.current["sshkit_backend"] = nil end - def initialize(host, &block) + def initialize(host, **options, &block) raise "Must pass a Host object" unless host.is_a? Host @host = host + @options = options @block = block + @config = options[:config] || SSHKit.config @pwd = nil @env = nil @@ -68,7 +70,7 @@ def capture(*args) end def background(*args) - SSHKit.config.deprecation_logger.log( + config.deprecation_logger.log( 'The background method is deprecated. Blame badly behaved pseudo-daemons!' ) options = args.extract_options!.merge(run_in_background: true) @@ -140,7 +142,7 @@ def download!(_remote, _local=nil, _options = {}) raise MethodUnavailableError e private def output - SSHKit.config.output + config.output end def create_command_and_execute(args, options) @@ -156,7 +158,9 @@ def pwd_path end def command(args, options) - SSHKit::Command.new(*args, options.merge({in: pwd_path, env: @env, host: @host, user: @user, group: @group})) + SSHKit::Command.new( + *args, options.merge({in: pwd_path, env: @env, host: @host, user: @user, group: @group, config: config}) + ) end end diff --git a/lib/sshkit/backends/local.rb b/lib/sshkit/backends/local.rb index 8108255f..e64b7344 100644 --- a/lib/sshkit/backends/local.rb +++ b/lib/sshkit/backends/local.rb @@ -6,8 +6,8 @@ module Backend class Local < Abstract - def initialize(_ = nil, &block) - super(Host.new(:local), &block) + def initialize(**options, &block) + super(Host.new(:local), **options, &block) end def upload!(local, remote, options = {}) diff --git a/lib/sshkit/command.rb b/lib/sshkit/command.rb index 7d71763e..9fa58c4f 100644 --- a/lib/sshkit/command.rb +++ b/lib/sshkit/command.rb @@ -10,7 +10,7 @@ class Command Failed = Class.new(SSHKit::StandardError) - attr_reader :command, :args, :options, :started_at, :started, :exit_status, :full_stdout, :full_stderr, :uuid + attr_reader :command, :args, :options, :started_at, :started, :exit_status, :full_stdout, :full_stderr, :uuid, :config # Initialize a new Command object # @@ -27,6 +27,7 @@ def initialize(*args) @options.symbolize_keys! @stdout, @stderr, @full_stdout, @full_stderr = String.new, String.new, String.new, String.new @uuid = Digest::SHA1.hexdigest(SecureRandom.random_bytes(10))[0..7] + @config = @options[:config] || SSHKit.config end def complete? @@ -147,7 +148,7 @@ def within(&_block) end def environment_hash - (SSHKit.config.default_env || {}).merge(options[:env] || {}) + (config.default_env || {}).merge(options[:env] || {}) end def environment_string @@ -176,8 +177,8 @@ def in_background(&_block) end def umask(&_block) - return yield unless SSHKit.config.umask - "umask #{SSHKit.config.umask} && #{yield}" + return yield unless config.umask + "umask #{config.umask} && #{yield}" end def group(&_block) @@ -213,7 +214,7 @@ def with_redaction def to_s if should_map? - [SSHKit.config.command_map[command.to_sym], *Array(args)].join(' ') + [config.command_map[command.to_sym], *Array(args)].join(' ') else command.to_s end @@ -239,19 +240,19 @@ def sanitize_command(cmd) def call_interaction_handler(stream_name, data, channel) interaction_handler = options[:interaction_handler] - interaction_handler = MappingInteractionHandler.new(interaction_handler) if interaction_handler.kind_of?(Hash) or interaction_handler.kind_of?(Proc) + interaction_handler = MappingInteractionHandler.new(interaction_handler, nil, config: config) if interaction_handler.kind_of?(Hash) or interaction_handler.kind_of?(Proc) interaction_handler.on_data(self, stream_name, data, channel) if interaction_handler.respond_to?(:on_data) end def log_reader_deprecation(stream) - SSHKit.config.deprecation_logger.log( + config.deprecation_logger.log( "The #{stream} method on Command is deprecated. " \ "The @#{stream} attribute will be removed in a future release. Use full_#{stream}() instead." ) end def log_writer_deprecation(stream) - SSHKit.config.deprecation_logger.log( + config.deprecation_logger.log( "The #{stream}= method on Command is deprecated. The @#{stream} attribute will be removed in a future release." ) end diff --git a/lib/sshkit/configuration.rb b/lib/sshkit/configuration.rb index e17489d5..2d234c0a 100644 --- a/lib/sshkit/configuration.rb +++ b/lib/sshkit/configuration.rb @@ -35,8 +35,8 @@ def default_runner_config def default_runner_config=(config_hash) config = config_hash.dup - SSHKit.config.default_runner = config.delete(:in) if config[:in] - @default_runner_config = config.merge(in: SSHKit.config.default_runner) + @default_runner = config.delete(:in) if config[:in] + @default_runner_config = config.merge(in: @default_runner) end def backend @@ -71,9 +71,9 @@ def format=(format) # # config.output = SSHKit::Formatter::Pretty.new($stdout) # - def use_format(formatter, *args) + def use_format(formatter, options = {}) klass = formatter.is_a?(Class) ? formatter : formatter_class(formatter) - self.output = klass.new($stdout, *args) + self.output = klass.new($stdout, options.merge(config: self)) end def command_map diff --git a/lib/sshkit/coordinator.rb b/lib/sshkit/coordinator.rb index 23f592c6..17ec9be0 100644 --- a/lib/sshkit/coordinator.rb +++ b/lib/sshkit/coordinator.rb @@ -9,27 +9,24 @@ def initialize(raw_hosts) @hosts = @raw_hosts.any? ? resolve_hosts : [] end - def each(options={}, &block) - if hosts - options = default_options.merge(options) + def each(**options, &block) + options = (options[:config] || SSHKit.config).default_runner_config.merge(options) + + if hosts case options[:in] when :parallel then Runner::Parallel when :sequence then Runner::Sequential when :groups then Runner::Group else options[:in] - end.new(hosts, options, &block).execute + end.new(hosts, **options, &block).execute else - Runner::Null.new(hosts, options, &block).execute + Runner::Null.new(hosts, **options, &block).execute end end private - def default_options - SSHKit.config.default_runner_config - end - def resolve_hosts @raw_hosts.collect { |rh| rh.is_a?(Host) ? rh : Host.new(rh) }.uniq end diff --git a/lib/sshkit/dsl.rb b/lib/sshkit/dsl.rb index ba9e2e64..6426b209 100644 --- a/lib/sshkit/dsl.rb +++ b/lib/sshkit/dsl.rb @@ -2,12 +2,12 @@ module SSHKit module DSL - def on(hosts, options={}, &block) - Coordinator.new(hosts).each(options, &block) + def on(hosts, **options, &block) + Coordinator.new(hosts).each(**options, &block) end - def run_locally(&block) - Backend::Local.new(&block).run + def run_locally(**options, &block) + Backend::Local.new(**options, &block).run end end diff --git a/lib/sshkit/formatters/abstract.rb b/lib/sshkit/formatters/abstract.rb index aa6ab125..a8082c97 100644 --- a/lib/sshkit/formatters/abstract.rb +++ b/lib/sshkit/formatters/abstract.rb @@ -7,7 +7,7 @@ module Formatter class Abstract extend Forwardable - attr_reader :original_output, :options + attr_reader :original_output, :options, :config def_delegators :@original_output, :read, :rewind def_delegators :@color, :colorize @@ -15,6 +15,7 @@ def initialize(output, options={}) @original_output = output @options = options @color = SSHKit::Color.new(output) + @config = options[:config] || SSHKit.config end %w(fatal error warn info debug).each do |level| diff --git a/lib/sshkit/formatters/pretty.rb b/lib/sshkit/formatters/pretty.rb index 9030de01..c25d0378 100644 --- a/lib/sshkit/formatters/pretty.rb +++ b/lib/sshkit/formatters/pretty.rb @@ -50,7 +50,7 @@ def format_message(verbosity, message, uuid=nil) private def write_message(verbosity, message, uuid=nil) - original_output << "#{format_message(verbosity, message, uuid)}\n" if verbosity >= SSHKit.config.output_verbosity + original_output << "#{format_message(verbosity, message, uuid)}\n" if verbosity >= config.output_verbosity end end diff --git a/lib/sshkit/mapping_interaction_handler.rb b/lib/sshkit/mapping_interaction_handler.rb index 884d5a85..ab017679 100644 --- a/lib/sshkit/mapping_interaction_handler.rb +++ b/lib/sshkit/mapping_interaction_handler.rb @@ -2,8 +2,9 @@ module SSHKit class MappingInteractionHandler - def initialize(mapping, log_level=nil) + def initialize(mapping, log_level=nil, **options) @log_level = log_level + @config = options[:config] || SSHKit.config @mapping_proc = \ case mapping when Hash @@ -40,7 +41,7 @@ def on_data(_command, stream_name, data, channel) private def log(message) - SSHKit.config.output.send(@log_level, message) unless @log_level.nil? + @config.output.send(@log_level, message) unless @log_level.nil? end end diff --git a/lib/sshkit/runners/abstract.rb b/lib/sshkit/runners/abstract.rb index 7373467d..d737ec4e 100644 --- a/lib/sshkit/runners/abstract.rb +++ b/lib/sshkit/runners/abstract.rb @@ -4,21 +4,22 @@ module Runner class Abstract - attr_reader :hosts, :options, :block + attr_reader :hosts, :options, :block, :config - def initialize(hosts, options = nil, &block) + def initialize(hosts, **options, &block) @hosts = Array(hosts) - @options = options || {} + @options = options @block = block + @config = options[:config] || SSHKit.config end private def backend(host, &block) if host.local? - SSHKit::Backend::Local.new(&block) + SSHKit::Backend::Local.new(config: config, &block) else - SSHKit.config.backend.new(host, &block) + config.backend.new(host, config: config, &block) end end diff --git a/lib/sshkit/runners/group.rb b/lib/sshkit/runners/group.rb index eaf9680c..02f1850c 100644 --- a/lib/sshkit/runners/group.rb +++ b/lib/sshkit/runners/group.rb @@ -5,8 +5,8 @@ module Runner class Group < Sequential attr_accessor :group_size - def initialize(hosts, options = nil, &block) - super(hosts, options, &block) + def initialize(hosts, **options, &block) + super(hosts, **options, &block) @group_size = @options[:limit] || 2 end diff --git a/lib/sshkit/runners/sequential.rb b/lib/sshkit/runners/sequential.rb index 8f7f8d23..772a39d0 100644 --- a/lib/sshkit/runners/sequential.rb +++ b/lib/sshkit/runners/sequential.rb @@ -5,8 +5,8 @@ module Runner class Sequential < Abstract attr_accessor :wait_interval - def initialize(hosts, options = nil, &block) - super(hosts, options, &block) + def initialize(hosts, **options, &block) + super(hosts, **options, &block) @wait_interval = @options[:wait] || 2 end diff --git a/test/unit/backends/test_abstract.rb b/test/unit/backends/test_abstract.rb index e7afac83..e91bd0fa 100644 --- a/test/unit/backends/test_abstract.rb +++ b/test/unit/backends/test_abstract.rb @@ -35,7 +35,7 @@ def test_execute_creates_and_executes_command_with_default_options assert_equal '/usr/bin/env ls -l /some/directory', backend.executed_command.to_command assert_equal( - {:raise_on_non_zero_exit=>true, :run_in_background=>false, :in=>nil, :env=>nil, :host=>ExampleBackend.example_host, :user=>nil, :group=>nil}, + {:raise_on_non_zero_exit=>true, :run_in_background=>false, :in=>nil, :env=>nil, :host=>ExampleBackend.example_host, :user=>nil, :group=>nil, :config=>SSHKit.config}, backend.executed_command.options ) end diff --git a/test/unit/test_configuration.rb b/test/unit/test_configuration.rb index 9ec79470..c035828b 100644 --- a/test/unit/test_configuration.rb +++ b/test/unit/test_configuration.rb @@ -109,7 +109,7 @@ def test_options_can_be_provided_to_formatter formatter = SSHKit.config.output assert_instance_of(TestFormatter, formatter) assert_equal($stdout, formatter.output) - assert_equal({ :color => false }, formatter.options) + assert_equal({ :color => false, :config => SSHKit.config }, formatter.options) end class TestFormatter diff --git a/test/unit/test_mapping_interaction_handler.rb b/test/unit/test_mapping_interaction_handler.rb index ee3e95ea..bbe7ecb0 100644 --- a/test/unit/test_mapping_interaction_handler.rb +++ b/test/unit/test_mapping_interaction_handler.rb @@ -14,13 +14,13 @@ def setup end def test_calls_send_data_with_mapped_input_when_stdout_matches - handler = MappingInteractionHandler.new('Server output' => "some input\n") + handler = MappingInteractionHandler.new({'Server output' => "some input\n"}) channel.expects(:send_data).with("some input\n") handler.on_data(nil, :stdout, 'Server output', channel) end def test_calls_send_data_with_mapped_input_when_stderr_matches - handler = MappingInteractionHandler.new('Server output' => "some input\n") + handler = MappingInteractionHandler.new({'Server output' => "some input\n"}) channel.expects(:send_data).with("some input\n") handler.on_data(nil, :stderr, 'Server output', channel) end