kontena-cli 1.2.0.pre1 → 1.2.0.pre2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/lib/kontena/callback.rb +2 -2
  4. data/lib/kontena/callbacks/master/01_clear_current_master_after_terminate.rb +1 -1
  5. data/lib/kontena/callbacks/master/deploy/50_authenticate_after_deploy.rb +6 -6
  6. data/lib/kontena/callbacks/master/deploy/55_create_initial_grid_after_deploy.rb +1 -1
  7. data/lib/kontena/callbacks/master/deploy/70_invite_self_after_deploy.rb +1 -1
  8. data/lib/kontena/callbacks/master/deploy/90_proptip_after_deploy.rb +1 -1
  9. data/lib/kontena/cli/apps/common.rb +6 -6
  10. data/lib/kontena/cli/apps/yaml/reader.rb +2 -2
  11. data/lib/kontena/cli/cloud/login_command.rb +4 -4
  12. data/lib/kontena/cli/cloud/master/add_command.rb +1 -1
  13. data/lib/kontena/cli/common.rb +5 -5
  14. data/lib/kontena/cli/config.rb +8 -8
  15. data/lib/kontena/cli/containers/exec_command.rb +1 -1
  16. data/lib/kontena/cli/localhost_web_server.rb +3 -3
  17. data/lib/kontena/cli/master/{users → user}/invite_command.rb +5 -5
  18. data/lib/kontena/cli/master/{users → user}/list_command.rb +1 -1
  19. data/lib/kontena/cli/master/{users → user}/remove_command.rb +3 -4
  20. data/lib/kontena/cli/master/{users/roles → user/role}/add_command.rb +4 -4
  21. data/lib/kontena/cli/master/{users/roles → user/role}/remove_command.rb +3 -4
  22. data/lib/kontena/cli/master/{users → user}/role_command.rb +3 -5
  23. data/lib/kontena/cli/master/user_command.rb +11 -0
  24. data/lib/kontena/cli/master/users_command.rb +8 -5
  25. data/lib/kontena/cli/master_command.rb +2 -1
  26. data/lib/kontena/cli/nodes/show_command.rb +3 -1
  27. data/lib/kontena/cli/plugins/install_command.rb +4 -4
  28. data/lib/kontena/cli/plugins/uninstall_command.rb +3 -2
  29. data/lib/kontena/cli/services/services_helper.rb +31 -9
  30. data/lib/kontena/cli/spinner.rb +4 -8
  31. data/lib/kontena/cli/stacks/build_command.rb +3 -1
  32. data/lib/kontena/cli/stacks/common.rb +44 -37
  33. data/lib/kontena/cli/stacks/install_command.rb +2 -2
  34. data/lib/kontena/cli/stacks/upgrade_command.rb +3 -1
  35. data/lib/kontena/cli/stacks/validate_command.rb +12 -10
  36. data/lib/kontena/cli/stacks/yaml/opto/service_instances_resolver.rb +1 -0
  37. data/lib/kontena/cli/stacks/yaml/opto/service_link_resolver.rb +1 -0
  38. data/lib/kontena/cli/stacks/yaml/opto/vault_cert_prompt_resolver.rb +1 -0
  39. data/lib/kontena/cli/stacks/yaml/opto/vault_resolver.rb +4 -2
  40. data/lib/kontena/cli/stacks/yaml/opto/vault_setter.rb +4 -3
  41. data/lib/kontena/cli/stacks/yaml/reader.rb +30 -7
  42. data/lib/kontena/cli/stacks/yaml/validations.rb +10 -0
  43. data/lib/kontena/cli/stacks/yaml/validator_v3.rb +88 -8
  44. data/lib/kontena/client.rb +14 -12
  45. data/lib/kontena/command.rb +10 -13
  46. data/lib/kontena/errors.rb +36 -0
  47. data/lib/kontena/plugin_manager.rb +8 -10
  48. data/lib/kontena/stacks_cache.rb +1 -1
  49. data/lib/kontena_cli.rb +5 -5
  50. data/spec/fixtures/stack-with-volumes.yml +33 -0
  51. data/spec/kontena/cli/master/{users → user}/invite_command_spec.rb +3 -3
  52. data/spec/kontena/cli/master/{users → user}/remove_command_spec.rb +3 -3
  53. data/spec/kontena/cli/master/{users/roles → user/role}/add_command_spec.rb +3 -3
  54. data/spec/kontena/cli/master/{users/roles → user/role}/remove_command_spec.rb +3 -3
  55. data/spec/kontena/cli/stacks/build_command_spec.rb +2 -2
  56. data/spec/kontena/cli/stacks/install_command_spec.rb +3 -3
  57. data/spec/kontena/cli/stacks/upgrade_command_spec.rb +6 -6
  58. data/spec/kontena/cli/stacks/yaml/opto/service_link_resolver_spec.rb +5 -0
  59. data/spec/kontena/cli/stacks/yaml/opto/vault_cert_prompt_resolver_spec.rb +6 -0
  60. data/spec/kontena/cli/stacks/yaml/reader_spec.rb +4 -2
  61. data/spec/kontena/client_spec.rb +19 -1
  62. data/spec/spec_helper.rb +2 -0
  63. metadata +19 -16
@@ -1,4 +1,5 @@
1
- require_relative '../../../util'
1
+ require 'kontena/cli/common'
2
+ require 'kontena/util'
2
3
 
3
4
  module Kontena::Cli::Stacks
4
5
  module YAML
@@ -73,8 +74,8 @@ module Kontena::Cli::Stacks
73
74
  )
74
75
  )
75
76
  )
76
- rescue Psych::SyntaxError => e
77
- raise "Error while parsing #{file}".colorize(:red)+ " " + e.message
77
+ rescue Psych::SyntaxError => ex
78
+ raise ex, "Error while parsing #{file} : #{ex.message}"
78
79
  end
79
80
 
80
81
  def fully_interpolated_yaml
@@ -92,8 +93,8 @@ module Kontena::Cli::Stacks
92
93
  )
93
94
  )
94
95
  )
95
- rescue Psych::SyntaxError => e
96
- raise "Error while parsing #{file}".colorize(:red)+ " " + e.message
96
+ rescue Psych::SyntaxError => ex
97
+ raise ex, "Error while parsing #{file} : #{ex.message}"
97
98
  end
98
99
 
99
100
  def raw_yaml
@@ -141,12 +142,13 @@ module Kontena::Cli::Stacks
141
142
  result[:expose] = fully_interpolated_yaml['expose']
142
143
  result[:errors] = errors unless skip_validation?
143
144
  result[:notifications] = notifications
144
- result[:services] = errors.count == 0 ? parse_services(service_name) : {}
145
+ result[:services] = errors.count.zero? ? parse_services(service_name) : {}
145
146
  unless skip_variables?
146
147
  result[:variables] = variables.to_h(values_only: true).reject do |k,_|
147
148
  k == 'GRID' || k == 'STACK' || variables.option(k).to.has_key?(:vault) || variables.option(k).from.has_key?(:vault)
148
149
  end
149
150
  end
151
+ result[:volumes] = errors.count.zero? ? parse_volumes : {}
150
152
  end
151
153
  result
152
154
  end
@@ -208,6 +210,19 @@ module Kontena::Cli::Stacks
208
210
  @validator ||= YAML::ValidatorV3.new
209
211
  end
210
212
 
213
+ def parse_volumes
214
+ volumes.each do |name, config|
215
+ if process_hash?(config)
216
+ volumes[name].delete('only_if')
217
+ volumes[name].delete('skip_if')
218
+ volumes[name] = process_volume(config)
219
+ else
220
+ volumes.delete(name)
221
+ end
222
+ end
223
+ volumes
224
+ end
225
+
211
226
  ##
212
227
  # @param [String] service_name - optional service to parse
213
228
  # @return [Hash]
@@ -264,9 +279,17 @@ module Kontena::Cli::Stacks
264
279
  service_config
265
280
  end
266
281
 
282
+ def process_volume(volume_config)
283
+ volume_config
284
+ end
285
+
286
+ def volumes
287
+ @volumes ||= fully_interpolated_yaml['volumes'] || {}
288
+ end
289
+
267
290
  # @return [Hash] - services from YAML file
268
291
  def services
269
- @services ||= fully_interpolated_yaml['services']
292
+ @services ||= fully_interpolated_yaml['services'] || {}
270
293
  end
271
294
 
272
295
  def from_external_file(filename, service_name)
@@ -69,5 +69,15 @@ module Kontena::Cli::Stacks::YAML
69
69
  def validate_options(service_config)
70
70
  HashValidator.validate(service_config, @schema, true)
71
71
  end
72
+
73
+ def validate_volume_options(volume_config)
74
+ HashValidator.validate(volume_config, volume_schema, true)
75
+ end
76
+
77
+ def volume_schema
78
+ {
79
+ 'external' => optional(-> (value) { value.is_a?(TrueClass) || (value.is_a?(Hash) && value['name'].is_a?(String)) })
80
+ }
81
+ end
72
82
  end
73
83
  end
@@ -6,6 +6,19 @@ module Kontena::Cli::Stacks
6
6
  require_relative 'validations'
7
7
  include Validations
8
8
 
9
+ KNOWN_TOP_LEVEL_KEYS = %w(
10
+ services
11
+ errors
12
+ volumes
13
+ networks
14
+ variables
15
+ stack
16
+ version
17
+ data
18
+ description
19
+ expose
20
+ )
21
+
9
22
  def initialize
10
23
  @schema = common_validations
11
24
  @schema['build'] = optional('stacks_valid_build')
@@ -27,24 +40,91 @@ module Kontena::Cli::Stacks
27
40
  errors: [],
28
41
  notifications: []
29
42
  }
43
+
44
+ result[:notifications] += (yaml.keys - KNOWN_TOP_LEVEL_KEYS).map do |key|
45
+ { key => "unknown top level key" }
46
+ end
47
+
30
48
  if yaml.key?('services')
31
- yaml['services'].each do |service, options|
32
- unless options.is_a?(Hash)
33
- result[:errors] << { service => { 'options' => 'must be a mapping not a string'} }
34
- next
49
+ if yaml['services'].is_a?(Hash)
50
+ yaml['services'].each do |service, options|
51
+ unless options.is_a?(Hash)
52
+ result[:errors] << { 'services' => { service => { 'options' => "must be a mapping not a #{options.class}"} } }
53
+ next
54
+ end
55
+ option_errors = validate_options(options)
56
+ result[:errors] << { 'services' => { service => option_errors.errors } } unless option_errors.valid?
57
+ if options['volumes']
58
+ mount_points = options['volumes'].inject(Hash.new(0)) { |hsh, vol| hsh[vol.split(':').last] += 1; hsh }
59
+ mount_points.each do |mount_point, occurences|
60
+ next unless occurences > 1
61
+ result[:errors] << { 'services' => { service => { 'volumes' => { mount_point => "mount point defined #{occurences} times" } } } }
62
+ end
63
+
64
+ options['volumes'].each do |volume|
65
+ if volume.include?(':')
66
+ volume_name, mount_point = volume.split(':', 2)
67
+ unless mount_point
68
+ result[:errors] << { 'services' => { service => { 'volumes' => { volume => 'mount point missing' } } } }
69
+ end
70
+ if volume_name
71
+ if yaml.key?('volumes')
72
+ unless yaml['volumes'][volume_name]
73
+ result[:errors] << { 'services' => { service => { 'volumes' => { volume_name => 'not found in top level volumes list' } } } }
74
+ end
75
+ else
76
+ result[:errors] << { 'services' => { service => { 'volumes' => { volume => 'defines volume name, but file does not contain volumes definitions' } } } }
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
35
82
  end
36
- option_errors = validate_options(options)
37
- result[:errors] << { service => option_errors.errors } unless option_errors.valid?
83
+ else
84
+ result[:errors] << { 'services' => "must be a mapping, not #{yaml['services'].class}" }
38
85
  end
39
86
  else
40
- result[:errors] << { 'file' => 'services missing' }
87
+ result[:notifications] << { 'file' => 'does not define any services' }
41
88
  end
89
+
42
90
  if yaml.key?('volumes')
43
- result[:notifications] << { 'volumes' => 'Kontena does not support volumes yet. To persist data just define service as stateful (stateful: true)' }
91
+ if yaml['volumes'].is_a?(Hash)
92
+ yaml['volumes'].each do |volume, options|
93
+ if options.is_a?(Hash)
94
+ option_errors = validate_volume_options(options)
95
+ if option_errors.valid?
96
+ if !options.key?('driver') && options.key?('driver_opts')
97
+ result[:errors] << { 'volumes' => { volume => { 'driver_opts' => 'defined without defining driver' } } }
98
+ end
99
+ if options.key?('external')
100
+ unless options['external'].is_a?(FalseClass)
101
+ ['driver', 'driver_opts', 'scope'].each do |key|
102
+ result[:errors] << { 'volumes' => { volume => { key => 'specified together with external' } } } if options.key?(key)
103
+ end
104
+ end
105
+ end
106
+ if options.key?('driver') && !options.key?('scope')
107
+ result[:errors] << { 'volumes' => { volume => { 'scope' => 'required value missing' } } }
108
+ end
109
+ else
110
+ result[:errors] << { 'volumes' => { volume => option_errors.errors } }
111
+ end
112
+ else
113
+ result[:errors] << { 'volumes' => { volume => { 'options' => "must be a mapping, not #{options.class}" } } }
114
+ end
115
+ end
116
+ else
117
+ result[:errors] << { 'volumes' => "must be a mapping, not #{yaml['volumes'].class}" }
118
+ end
44
119
  end
120
+
45
121
  if yaml.key?('networks')
46
122
  result[:notifications] << { 'networks' => 'Kontena does not support multiple networks yet. You can reference services with Kontena\'s internal DNS (service_name.kontena.local)' }
47
123
  end
124
+
125
+ if (yaml['volumes'].nil? || yaml['volumes'].empty?) && (yaml['services'].nil? || yaml['services'].empty?)
126
+ result[:errors] << { 'file' => 'does not list any services or volumes' }
127
+ end
48
128
  result
49
129
  end
50
130
  end
@@ -47,7 +47,7 @@ module Kontena
47
47
  uri = URI.parse(@api_url)
48
48
  @host = uri.host
49
49
 
50
- @logger = Logger.new(ENV["DEBUG"] ? STDERR : STDOUT)
50
+ @logger = Logger.new(ENV["DEBUG"] ? $stderr : $stdout)
51
51
  @logger.level = ENV["DEBUG"].nil? ? Logger::INFO : Logger::DEBUG
52
52
  @logger.progname = 'CLIENT'
53
53
 
@@ -139,8 +139,8 @@ module Kontena
139
139
  logger.debug "Requesting user info from #{final_path}"
140
140
  request(path: final_path)
141
141
  true
142
- rescue
143
- logger.debug "Authentication verification exception: #{$!} #{$!.message} #{$!.backtrace}"
142
+ rescue => ex
143
+ logger.debug "Authentication verification exception: #{ex.class.name} : #{ex.message}\n#{ex.backtrace.join("\n ")}"
144
144
  false
145
145
  end
146
146
 
@@ -172,8 +172,8 @@ module Kontena
172
172
  # @return [String] version_string
173
173
  def server_version
174
174
  request(auth: false, expects: 200)['version']
175
- rescue
176
- logger.debug "Server version exception: #{$!} #{$!.message}"
175
+ rescue => ex
176
+ logger.debug "Server version exception: #{ex.class.name} : #{ex.message}\n#{ex.backtrace.join("\n ")}"
177
177
  nil
178
178
  end
179
179
 
@@ -369,8 +369,8 @@ module Kontena
369
369
  else
370
370
  {}
371
371
  end
372
- rescue
373
- logger.debug "Access token refresh exception: #{$!} - #{$!.message} #{$!.backtrace}"
372
+ rescue => ex
373
+ logger.debug "Access token refresh exception: #{ex.class.name} : #{ex.message}\n#{ex.backtrace.join("\n ")}"
374
374
  false
375
375
  end
376
376
 
@@ -418,8 +418,8 @@ module Kontena
418
418
  logger.debug "Got null or bad response to refresh request: #{last_response.inspect}"
419
419
  false
420
420
  end
421
- rescue
422
- logger.debug "Access token refresh exception: #{$!} - #{$!.message} #{$!.backtrace}"
421
+ rescue => ex
422
+ logger.debug "Access token refresh exception: #{ex.class.name} : #{ex.message}\n#{ex.backtrace.join("\n ")}"
423
423
  false
424
424
  end
425
425
 
@@ -509,8 +509,8 @@ module Kontena
509
509
  # @return [Hash,Object,NilClass]
510
510
  def parse_json(json)
511
511
  JSON.parse(json)
512
- rescue
513
- logger.debug "JSON parse exception: #{$!} : #{$!.message}"
512
+ rescue => ex
513
+ logger.debug "JSON parse exception: #{ex.class.name} : #{ex.message}"
514
514
  nil
515
515
  end
516
516
 
@@ -531,7 +531,9 @@ module Kontena
531
531
  def handle_error_response(response)
532
532
  data = parse_response(response)
533
533
 
534
- if data.is_a?(Hash) && data.has_key?('error')
534
+ if data.is_a?(Hash) && data.has_key?('error') && data['error'].is_a?(Hash)
535
+ raise Kontena::Errors::StandardErrorHash.new(response.status, response.reason_phrase, data['error'])
536
+ elsif data.is_a?(Hash) && data.has_key?('error')
535
537
  raise Kontena::Errors::StandardError.new(response.status, data['error'])
536
538
  elsif data.is_a?(String) && !data.empty?
537
539
  raise Kontena::Errors::StandardError.new(response.status, data)
@@ -178,7 +178,7 @@ class Kontena::Command < Clamp::Command
178
178
  end
179
179
 
180
180
  def run(arguments)
181
- ENV["DEBUG"] && STDERR.puts("Running #{self} -- callback matcher = '#{self.class.callback_matcher.nil? ? "nil" : self.class.callback_matcher.map(&:to_s).join(' ')}'")
181
+ ENV["DEBUG"] && $stderr.puts("Running #{self} -- callback matcher = '#{self.class.callback_matcher.nil? ? "nil" : self.class.callback_matcher.map(&:to_s).join(' ')}'")
182
182
  @arguments = arguments
183
183
 
184
184
  run_callbacks :before_parse unless help_requested?
@@ -202,29 +202,26 @@ class Kontena::Command < Clamp::Command
202
202
  run_callbacks :after unless help_requested?
203
203
  exit(@exit_code) if @exit_code.to_i > 0
204
204
  @result
205
- rescue Excon::Errors::SocketError => exc
206
- if exc.message.include?('Unable to verify certificate')
205
+ rescue Excon::Errors::SocketError => ex
206
+ if ex.message.include?('Unable to verify certificate')
207
207
  $stderr.puts " [#{Kontena.pastel.red('error')}] The server uses a certificate signed by an unknown authority."
208
208
  $stderr.puts " You can trust this server by copying server CA pem file to: #{Kontena.pastel.yellow("~/.kontena/certs/<hostname>.pem")}"
209
209
  $stderr.puts " Protip: you can bypass the certificate check by setting #{Kontena.pastel.yellow('SSL_IGNORE_ERRORS=true')} env variable, but any data you send to the server could be intercepted by others."
210
210
  abort
211
211
  else
212
- abort(exc.message)
212
+ abort(ex.message)
213
213
  end
214
- rescue Kontena::Errors::StandardError => exc
215
- raise exc if ENV['DEBUG']
216
- $stderr.puts " [#{Kontena.pastel.red('error')}] #{exc.message}"
217
- abort
214
+ rescue Kontena::Errors::StandardError => ex
215
+ raise ex if ENV['DEBUG']
216
+ abort(" [#{Kontena.pastel.red('error')}] #{ex.class.name} : #{ex.message}")
218
217
  rescue Errno::EPIPE
219
218
  # If user is piping the command outputs to some other command that might exit before CLI has outputted everything
220
219
  abort
221
220
  rescue Clamp::HelpWanted, Clamp::UsageError
222
221
  raise
223
- rescue => exc
224
- raise exc if ENV['DEBUG']
225
- $stderr.puts " [#{Kontena.pastel.red('error')}] #{exc.message}"
226
- $stderr.puts " Rerun the command with environment DEBUG=true set to get the full exception"
227
- abort
222
+ rescue => ex
223
+ raise ex if ENV['DEBUG']
224
+ abort(" [#{Kontena.pastel.red('error')}] #{ex.class.name} : #{ex.message}\n Rerun the command with environment DEBUG=true set to get the full exception")
228
225
  end
229
226
  end
230
227
 
@@ -4,10 +4,46 @@ module Kontena
4
4
 
5
5
  attr_reader :status
6
6
 
7
+ # @param status [Fixnum] HTTP response status
8
+ # @param message [String] short error message
7
9
  def initialize(status, message)
8
10
  @status = status
9
11
  super(message)
10
12
  end
11
13
  end
14
+
15
+ # The normal {error: {foo: "invalid foo"}} error response format used by the API
16
+ class StandardErrorHash < StandardError
17
+ attr_reader :errors
18
+
19
+ # @param errors [Hash]
20
+ def initialize(status, message, errors)
21
+ super(status, message)
22
+ @errors = errors
23
+ end
24
+
25
+ # Render as indented YAML
26
+ def errors_message(indent: "\t")
27
+ @errors.to_yaml.lines[1..-1].map{|line| "#{indent}#{line}" }.join
28
+ end
29
+
30
+ # Render the full multi-line message including YAML-formatted errors
31
+ def message
32
+ "#{super}:\n#{errors_message}"
33
+ end
34
+ end
35
+
36
+ # An error with an array of additional details
37
+ class StandardErrorArray < Kontena::Errors::StandardError
38
+ # @param details [Array<String>]
39
+ def initialize(status, message, details)
40
+ super(status, message)
41
+ @details = details
42
+ end
43
+
44
+ def message
45
+ "#{super}:\n#{@details.map{|msg| "\t" + msg}.join("\n")}"
46
+ end
47
+ end
12
48
  end
13
49
  end
@@ -171,23 +171,21 @@ module Kontena
171
171
  plugins << spec
172
172
  else
173
173
  plugin_name = spec.name.sub('kontena-plugin-', '')
174
- STDERR.puts " [#{Kontena.pastel.red('error')}] Plugin #{Kontena.pastel.cyan(plugin_name)} (#{spec.version}) is not compatible with the current cli version."
175
- STDERR.puts " To update the plugin, run 'kontena plugin install #{plugin_name}'"
176
- end
177
- rescue LoadError => exc
178
- STDERR.puts " [#{Kontena.pastel.red('error')}] Failed to load plugin: #{spec.name}"
179
- if ENV['DEBUG']
180
- STDERR.puts exc.message
181
- STDERR.puts exc.backtrace.join("\n")
174
+ $stderr.puts " [#{Kontena.pastel.red('error')}] Plugin #{Kontena.pastel.cyan(plugin_name)} (#{spec.version}) is not compatible with the current cli version."
175
+ $stderr.puts " To update the plugin, run 'kontena plugin install #{plugin_name}'"
182
176
  end
177
+ rescue LoadError => ex
178
+ $stderr.puts " [#{Kontena.pastel.red('error')}] Failed to load plugin: #{spec.name}"
179
+ ENV['DEBUG'] && $stderr.puts("#{ex.class.name} : #{ex.message}\n#{ex.backtrace.join("\n ")}")
183
180
  exit 1
184
181
  end
185
182
  end
186
183
  end
187
184
  end
188
185
  plugins
189
- rescue => exc
190
- STDERR.puts exc.message
186
+ rescue => ex
187
+ $stderr.puts Kontena.pastel.red(ex.message)
188
+ ENV['DEBUG'] && $stderr.puts("#{ex.class.name} : #{ex.message}\n#{ex.backtrace.join("\n ")}")
191
189
  end
192
190
 
193
191
  def prefix(plugin_name)
@@ -69,7 +69,7 @@ module Kontena
69
69
  end
70
70
 
71
71
  def dputs(msg)
72
- ENV["DEBUG"] && STDERR.puts(msg)
72
+ ENV["DEBUG"] && $stderr.puts(msg)
73
73
  end
74
74
 
75
75
  def cache(stack, version = nil)
data/lib/kontena_cli.rb CHANGED
@@ -19,11 +19,11 @@ module Kontena
19
19
  ENV["DEBUG"] && puts("Command completed, result: #{result.inspect} status: 0")
20
20
  return 0 if returning == :status
21
21
  return result if returning == :result
22
- rescue SystemExit
23
- ENV["DEBUG"] && STDERR.puts("Command completed with failure, result: #{result.inspect} status: #{$!.status}")
22
+ rescue SystemExit => ex
23
+ ENV["DEBUG"] && $stderr.puts("Command completed with failure, result: #{result.inspect} status: #{ex.status}")
24
24
  returning == :status ? $!.status : nil
25
- rescue
26
- ENV["DEBUG"] && STDERR.puts("Command raised #{$!} with message: #{$!.message}\n #{$!.backtrace.join(" \n")}")
25
+ rescue => ex
26
+ ENV["DEBUG"] && $stderr.puts("Command raised #{ex} with message: #{ex.message}\n#{ex.backtrace.join("\n ")}")
27
27
  returning == :status ? 1 : nil
28
28
  end
29
29
 
@@ -95,7 +95,7 @@ require 'retriable'
95
95
  Retriable.configure do |c|
96
96
  c.on_retry = Proc.new do |exception, try, elapsed_time, next_interval|
97
97
  return true unless ENV["DEBUG"]
98
- puts "Retriable retry: #{try} - Exception: #{exception} - #{exception.message}. Elapsed: #{elapsed_time} Next interval: #{next_interval}"
98
+ puts "Retriable retry: #{try} - Exception: #{exception.class.name} - #{exception.message}. Elapsed: #{elapsed_time} Next interval: #{next_interval}"
99
99
  end
100
100
  end
101
101