diff --git a/.rubocop.yml b/.rubocop.yml index 4c9b65d9..3dfd8f91 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,8 +1,8 @@ AllCops: + TargetRubyVersion: "2.4" DisplayCopNames: true DisplayStyleGuide: true SuggestExtensions: false - TargetRubyVersion: 2.4 Exclude: - "module/**/*" - "vendor/**/*" diff --git a/lib/mcollective/application.rb b/lib/mcollective/application.rb index e2939317..85aeae13 100644 --- a/lib/mcollective/application.rb +++ b/lib/mcollective/application.rb @@ -31,6 +31,24 @@ def description(descr) self[:description] = descr end + # Executes an external program instead of implement the logic in ruby + # + # @param [Hash] command the command to run + # @option command [String] :command the command to run + # @option command [Array] :args arguments to pass to the command + def external(command) + self[:external] = command + end + + # Executes an external program to show help instead of supplying options + # + # @param [Hash] command the command to run + # @option command [String] :command the command to run + # @option command [Array] :args arguments to pass to the command + def external_help(command) + self[:external_help] = command + end + # Supplies usage information, calling multiple times will # create multiple usage lines in --help output def usage(usage) @@ -82,7 +100,9 @@ def intialize_application_options @application_options = {:description => nil, :usage => [], :cli_arguments => [], - :exclude_arg_sections => []} + :exclude_arg_sections => [], + :external => nil, + :external_help => nil} end end @@ -267,7 +287,14 @@ def application_failure(err, err_dest=$stderr) exit 1 end + def external_help + ext = application_options[:external_help] + exec(ext[:command], ext[:args]) + end + def help + return external_help if application_options[:external_help] + application_parse_options(true) end @@ -275,6 +302,8 @@ def help # the main as supplied by the user. Disconnects when done and pass any exception # onto the application_failure helper def run + return external_main if application_options[:external] + application_parse_options validate_configuration(configuration) if respond_to?(:validate_configuration) @@ -293,6 +322,14 @@ def disconnect rescue # rubocop:disable Lint/SuppressedException end + def external_main + ext = application_options[:external] + args = ext[:args] || [] + args.concat(ARGV) + + exec(ext[:command], *args) + end + # Fake abstract class that logs if the user tries to use an application without # supplying a main override method. def main diff --git a/lib/mcollective/application/ping.rb b/lib/mcollective/application/ping.rb index 15b12849..9a09aa41 100644 --- a/lib/mcollective/application/ping.rb +++ b/lib/mcollective/application/ping.rb @@ -2,79 +2,7 @@ module MCollective class Application::Ping < Application # rubocop:disable Style/ClassAndModuleChildren description "Ping all nodes" - option :graph, - :description => "Shows a graph of ping distribution", - :arguments => ["--graph", "-g"], - :default => false, - :type => :bool - - # Convert the times structure into a array representing - # buckets of responses in 50 ms intervals. Return a small - # sparkline graph using UTF8 characters - def spark(resp_times) - return "" unless configuration[:graph] || Config.instance.pluginconf["rpc.graph"] - - ticks = %w[▁ ▂ ▃ ▄ ▅ ▆ ▇] - - histo = {} - - # round each time to its nearest 50ms - # and keep a count for each 50ms - resp_times.each do |time| - time = Integer(time + 50 - (time % 50)) - histo[time] ||= 0 - histo[time] += 1 - end - - # set the 50ms intervals that saw no traffic to 0 - ((histo.keys.max - histo.keys.min) / 50).times do |i| - time = (i * 50) + histo.keys.min - histo[time] = 0 unless histo[time] - end - - # get a numerically sorted list of times - histo = histo.keys.sort.map {|k| histo[k]} - - scale = ticks.size - 1 - distance = histo.max.to_f / scale - - histo.map do |val| - tick = (val / distance).round - tick = 0 if tick < 0 - - ticks[tick] - end.join - end - - def main - # If the user did not override the default timeout include the discovery timeout - if options[:timeout] == 5 - discovery_timeout = options[:disctimeout] || Config.instance.discovery_timeout || 0 - options[:timeout] = options[:timeout] + discovery_timeout - end - client = MCollective::Client.new(options) - - start = Time.now.to_f - times = [] - - client.req("ping", "discovery") do |resp| - times << (Time.now.to_f - start) * 1000 - - puts "%-40s time=%.2f ms" % [resp[:senderid], times.last] - end - - puts("\n\n---- ping statistics ----") - - if !times.empty? - sum = times.inject(0) {|acc, i| acc + i} - avg = sum / times.length.to_f - - puts "%d replies max: %.2f min: %.2f avg: %.2f %s" % [times.size, times.max, times.min, avg, spark(times)] - else - puts("No responses received") - end - - halt client.stats - end + external(:command => "choria", :args => ["ping"]) + external_help(:command => "choria", :args => ["ping", "--help"]) end end diff --git a/spec/unit/mcollective/application_spec.rb b/spec/unit/mcollective/application_spec.rb index 26a95632..390c4b76 100755 --- a/spec/unit/mcollective/application_spec.rb +++ b/spec/unit/mcollective/application_spec.rb @@ -14,7 +14,9 @@ module MCollective expect(Application.application_options).to eq({:description => nil, :usage => [], :cli_arguments => [], - :exclude_arg_sections => []}) + :exclude_arg_sections => [], + :external => nil, + :external_help => nil}) end end @@ -36,7 +38,9 @@ module MCollective expect(Application.intialize_application_options).to eq({:description => nil, :usage => [], :cli_arguments => [], - :exclude_arg_sections => []}) + :exclude_arg_sections => [], + :external => nil, + :external_help => nil}) end end