prometheus-splash 0.5.0 → 0.5.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d510e4761e365c1ee36881fb1a3a4a99a7dbe7965958841497cdcaaadfb0c1b3
4
- data.tar.gz: 4f01f486135696ef0142d42362379e59868b1265ce367b3e3aac9853fcc48336
3
+ metadata.gz: 5fd95d116c0f265b310c0ea710e909ab4022a5920c3c234524f2a1dcf9d21d0e
4
+ data.tar.gz: e21840114c3ea30be45b3766a14f00991b2a6629a44084ff6898ae39d88090c6
5
5
  SHA512:
6
- metadata.gz: 8b5c84b54b2098f9b027408ab8419fb19964feb1056607d090802acc793c2ccd6a9b98c1c8c2ca91334ccc8a36de88c1bf6cd674b6f5ef9df33a40debbfe84f5
7
- data.tar.gz: 1d93b819d8a9592495271a24bdc3e69e63a15489f5885faa729a8e42428a68dada73748ea8440c1338625a36c89d84a260e3bc9cdafa8fb869747864edc001f4
6
+ metadata.gz: ae5a2ed4a5100284605b7688e73f3fb59d008a7be9ce6e4050bfc5b9656663e4c2bb72f24f962b98544702a2bf0f2d889f6bd757a12ecb22c52a085cb70857b3
7
+ data.tar.gz: f9cf202cb9d0818e164fb35c705ab1593ae77e6ce28d06dc18d095d6e7c8c46cb45854f8bad0a661e0edba8f145acbc850ea5163e734b54094cfa50d4db5836b
@@ -81,3 +81,34 @@
81
81
  * quiet mode + no-colors and no-emoji #5
82
82
  * correlation id in log for daemon #15
83
83
  * systemd Splashd service installation #32
84
+
85
+
86
+ ## V 0.5.1 2020/04/17
87
+
88
+ ### CHANGES
89
+
90
+ * short Alias for commands without --no-[xxxx] #38
91
+ * REFACTO : namespaces
92
+ * Splash::Commands
93
+ * Splash::Log
94
+ * Splash::Daemon
95
+ * Splash::Daemon::Orchestrator
96
+
97
+
98
+ ### FEATURES
99
+
100
+ * flush backend arg in config #41
101
+ * adding global --debug flag
102
+ * adding splash Daemon metrics #25
103
+
104
+ ### DOC
105
+
106
+ * default value of mon scheduling 20s => 1m in ansible splash.yml
107
+
108
+
109
+ ### FIX
110
+
111
+ * Ansible Splash role handler error
112
+ * Ansible Splash role logrotate copytruncate for splash logs
113
+ * Prometheus Registry mismatch=> cumulative metrics on each groups #42
114
+ * logger Dual level conservation #43
@@ -34,6 +34,8 @@
34
34
  :daemon:
35
35
  :logmon_scheduling:
36
36
  :every: 20s
37
+ :metrics_scheduling:
38
+ :every: 20s
37
39
  :process_name: "Splash : daemon."
38
40
  :paths:
39
41
  :pid_path: /var/run/splash
@@ -36,6 +36,10 @@ module Splash
36
36
  return ::File.exist?("#{@path}/#{suffix_trace(options[:key])}")
37
37
  end
38
38
 
39
+ def flush
40
+ Dir.glob("#{@path}/*.trace").each { |file| ::File.delete(file)}
41
+ end
42
+
39
43
  private
40
44
  def suffix_trace(astring)
41
45
  return "#{astring}.trace"
@@ -9,7 +9,7 @@ module Splash
9
9
  conf = { :host => @config[:host], :port => @config[:port], :db => @config[:base].to_i}
10
10
  conf[:password] = @config[:auth] if @config[:auth]
11
11
  @store = ::Redis.new conf
12
- @redis_cli_cmd = `which redis-cli`
12
+ #@redis_cli_cmd = `which redis-cli`
13
13
  @store.auth(@config[:auth]) if @config[:auth]
14
14
  end
15
15
 
@@ -37,8 +37,8 @@ module Splash
37
37
  end
38
38
 
39
39
  def flush
40
- `#{@redis_cli_cmd} -n 3 flushdb`
41
- # @@store.flushdb
40
+ #`#{@redis_cli_cmd} -n #{@config[:base]} flushdb`
41
+ @store.flushdb
42
42
  end
43
43
 
44
44
  def exist?(options)
@@ -11,14 +11,16 @@ class CLI < Thor
11
11
  super
12
12
  log = get_logger
13
13
  options[:colors.to_s]
14
+ log.level = :debug if options[:debug]
14
15
  log.emoji = options[:emoji.to_s]
15
16
  log.color = options[:colors.to_s]
17
+ log.debug "DEBUG activated" if options[:debug]
16
18
  end
17
19
 
18
20
  class_option :quiet, :desc => "Quiet mode, limit output to :fatal", :aliases => "-q", :type => :boolean
19
21
  class_option :emoji, :desc => "Display Emoji", :type => :boolean, :default => true
20
22
  class_option :colors, :desc => "Display colors", :type => :boolean, :default => true
21
-
23
+ class_option :debug, :desc => "Set log level to :debug", :aliases => "-d", :type => :boolean
22
24
 
23
25
 
24
26
  include CLISplash
@@ -9,6 +9,7 @@ module CLISplash
9
9
  include Splash::Transports
10
10
  include Splash::Templates
11
11
  include Splash::Loggers
12
+ include Splash::Commands
12
13
 
13
14
  desc "execute NAME", "run for command/sequence or ack result"
14
15
  long_desc <<-LONGDESC
@@ -21,10 +22,10 @@ module CLISplash
21
22
  with --hostname, execute on an other Splash daemon node
22
23
  LONGDESC
23
24
  option :trace, :type => :boolean, :default => true
24
- option :ack, :type => :boolean, negate: false
25
+ option :ack, :type => :boolean, negate: false, :aliases => "-a"
25
26
  option :notify, :type => :boolean, :default => true
26
27
  option :callback, :type => :boolean, :default => true
27
- option :hostname, :type => :string
28
+ option :hostname, :type => :string, :aliases => "-H"
28
29
  def execute(name)
29
30
  log = get_logger
30
31
  log.level = :fatal if options[:quiet]
@@ -60,7 +61,7 @@ module CLISplash
60
61
  res[:more] = "Remote command : :execute_command Scheduled"
61
62
  splash_exit res
62
63
  else
63
- command = Splash::CommandWrapper::new(name)
64
+ command = CommandWrapper::new(name)
64
65
  if options[:ack] then
65
66
  splash_exit command.ack
66
67
  end
@@ -83,7 +84,7 @@ module CLISplash
83
84
  WARNING : scheduling by CLI are not percisted, so use it only for specifics cases.\n
84
85
  NOTES : Scheduling, force trace, notifying and callback.
85
86
  LONGDESC
86
- option :hostname, :type => :string, :default => Socket.gethostname
87
+ option :hostname, :type => :string, :default => Socket.gethostname, :aliases => "-H"
87
88
  option :at, :type => :string
88
89
  option :in, :type => :string
89
90
  def schedule(name)
@@ -121,7 +122,7 @@ module CLISplash
121
122
  Show commands sequence tree\n
122
123
  with --hostname, ask other Splash daemon via transport\n
123
124
  LONGDESC
124
- option :hostname, :type => :string
125
+ option :hostname, :type => :string, :aliases => "-H"
125
126
  def treeview(command)
126
127
  depht = 0
127
128
  log = get_logger
@@ -169,8 +170,8 @@ module CLISplash
169
170
  with --detail, show command details\n
170
171
  with --hostname, ask other Splash daemon via transport\n
171
172
  LONGDESC
172
- option :detail, :type => :boolean
173
- option :hostname, :type => :string
173
+ option :detail, :type => :boolean, :aliases => "-D"
174
+ option :hostname, :type => :string, :aliases => "-H"
174
175
  def list
175
176
  log = get_logger
176
177
  list = {}
@@ -218,7 +219,7 @@ module CLISplash
218
219
  Show specific configured command COMMAND\n
219
220
  with --hostname <HOSTNAME>, an other Splash monitored server (only with Redis backend configured)
220
221
  LONGDESC
221
- option :hostname, :type => :string
222
+ option :hostname, :type => :string, :aliases => "-H"
222
223
  def show(command)
223
224
  log = get_logger
224
225
  list = {}
@@ -264,7 +265,7 @@ module CLISplash
264
265
  Show last running result for specific configured command COMMAND\n
265
266
  with --hostname <HOSTNAME>, an other Splash monitored server (only with Redis backend configured)
266
267
  LONGDESC
267
- option :hostname, :type => :string
268
+ option :hostname, :type => :string, :aliases => "-H"
268
269
  def lastrun(command)
269
270
  log = get_logger
270
271
  backend = get_backend :execution_trace
@@ -307,10 +308,10 @@ module CLISplash
307
308
  with --detail, get major informations of each reports\n
308
309
  --all and --hostname are exclusives
309
310
  LONGDESC
310
- option :pattern, :type => :string
311
- option :hostname, :type => :string
312
- option :all, :type => :boolean, :negate => false
313
- option :detail, :type => :boolean
311
+ option :pattern, :type => :string, :aliases => "-p"
312
+ option :hostname, :type => :string, :aliases => "-H"
313
+ option :all, :type => :boolean, :negate => false, :aliases => "-A"
314
+ option :detail, :type => :boolean, :aliases => "-D"
314
315
  def getreportlist
315
316
  log = get_logger
316
317
  options[:hostname] = Socket.gethostname if options[:hostname] == 'hostname'
@@ -13,7 +13,7 @@ module CLISplash
13
13
  Setup installation fo Splash\n
14
14
  with --preserve, preserve from reinstallation of the config
15
15
  LONGDESC
16
- option :preserve, :type => :boolean
16
+ option :preserve, :type => :boolean, :aliases => "-P"
17
17
  def setup
18
18
  acase = run_as_root :setupsplash, options
19
19
  splash_exit acase
@@ -40,6 +40,12 @@ module CLISplash
40
40
  splash_exit acase
41
41
  end
42
42
 
43
+ desc "flushbackend", "Flush configured backend"
44
+ def flushbackend
45
+ acase = run_as_root :flush_backend
46
+ splash_exit acase
47
+ end
48
+
43
49
 
44
50
  end
45
51
 
@@ -2,13 +2,13 @@
2
2
  module CLISplash
3
3
 
4
4
  class CLIController < Thor
5
- include Splash::LogsMonitor::DaemonController
5
+ include Splash::Daemon::Controller
6
6
  include Splash::Transports
7
7
  include Splash::Exiter
8
8
  include Splash::Loggers
9
9
 
10
10
 
11
- option :foreground, :type => :boolean
11
+ option :foreground, :type => :boolean, :aliases => "-F"
12
12
  option :purge, :type => :boolean, default: true
13
13
  option :scheduling, :type => :boolean, default: true
14
14
  long_desc <<-LONGDESC
@@ -4,12 +4,13 @@ module CLISplash
4
4
  class Logs < Thor
5
5
  include Splash::Config
6
6
  include Splash::Exiter
7
+ include Splash::Logs
7
8
 
8
9
 
9
10
  desc "analyse", "analyze logs in config"
10
11
  def analyse
11
12
  log = get_logger
12
- results = Splash::LogScanner::new
13
+ results = LogScanner::new
13
14
  res = results.analyse
14
15
  log.info "SPlash Configured logs status :"
15
16
  full_status = true
@@ -42,7 +43,7 @@ module CLISplash
42
43
  def monitor
43
44
  log = get_logger
44
45
  log.level = :fatal if options[:quiet]
45
- result = Splash::LogScanner::new
46
+ result = LogScanner::new
46
47
  result.analyse
47
48
  splash_exit result.notify
48
49
 
@@ -67,7 +68,7 @@ module CLISplash
67
68
  Show configured logs monitoring\n
68
69
  with --detail, show logs monitor details
69
70
  LONGDESC
70
- option :detail, :type => :boolean
71
+ option :detail, :type => :boolean, :aliases => "-D"
71
72
  def list
72
73
  log = get_logger
73
74
  log.info "Splash configured log monitoring :"
@@ -1,146 +1,148 @@
1
1
  # coding: utf-8
2
2
  module Splash
3
- class CommandWrapper
4
- include Splash::Templates
5
- include Splash::Config
6
- include Splash::Helpers
7
- include Splash::Backends
8
- include Splash::Exiter
9
- include Splash::Transports
3
+ module Commands
4
+ class CommandWrapper
5
+ include Splash::Templates
6
+ include Splash::Config
7
+ include Splash::Helpers
8
+ include Splash::Backends
9
+ include Splash::Exiter
10
+ include Splash::Transports
10
11
 
11
12
 
12
- @@registry = Prometheus::Client.registry
13
- @@metric_exitcode = Prometheus::Client::Gauge.new(:errorcode, docstring: 'SPLASH metric batch errorcode')
14
- @@metric_time = Prometheus::Client::Gauge.new(:exectime, docstring: 'SPLASH metric batch execution time')
15
- @@registry.register(@@metric_exitcode)
16
- @@registry.register(@@metric_time)
13
+ @@registry = Prometheus::Client::Registry::new
14
+ @@metric_exitcode = Prometheus::Client::Gauge.new(:errorcode, docstring: 'SPLASH metric batch errorcode')
15
+ @@metric_time = Prometheus::Client::Gauge.new(:exectime, docstring: 'SPLASH metric batch execution time')
16
+ @@registry.register(@@metric_exitcode)
17
+ @@registry.register(@@metric_time)
17
18
 
18
- def initialize(name)
19
- @config = get_config
20
- @url = "http://#{@config.prometheus_pushgateway_host}:#{@config.prometheus_pushgateway_port}"
21
- @name = name
22
- unless @config.commands.keys.include? @name.to_sym then
23
- splash_exit case: :not_found, more: "command #{@name} is not defined in configuration"
19
+ def initialize(name)
20
+ @config = get_config
21
+ @url = "http://#{@config.prometheus_pushgateway_host}:#{@config.prometheus_pushgateway_port}"
22
+ @name = name
23
+ unless @config.commands.keys.include? @name.to_sym then
24
+ splash_exit case: :not_found, more: "command #{@name} is not defined in configuration"
25
+ end
24
26
  end
25
- end
26
27
 
27
- def ack
28
- get_logger.info "Sending ack for command : '#{@name}'"
29
- notify(0,0)
30
- end
28
+ def ack
29
+ get_logger.info "Sending ack for command : '#{@name}'"
30
+ notify(0,0)
31
+ end
31
32
 
32
- def notify(value,time)
33
- unless verify_service host: @config.prometheus_pushgateway_host ,port: @config.prometheus_pushgateway_port then
34
- return { :case => :service_dependence_missing, :more => "Prometheus Notification not send."}
33
+ def notify(value,time)
34
+ unless verify_service host: @config.prometheus_pushgateway_host ,port: @config.prometheus_pushgateway_port then
35
+ return { :case => :service_dependence_missing, :more => "Prometheus Notification not send."}
36
+ end
37
+ @@metric_exitcode.set(value)
38
+ @@metric_time.set(time)
39
+ hostname = Socket.gethostname
40
+ Prometheus::Client::Push.new(@name, hostname, @url).add(@@registry)
41
+ return { :case => :quiet_exit}
35
42
  end
36
- @@metric_exitcode.set(value)
37
- @@metric_time.set(time)
38
- hostname = Socket.gethostname
39
- Prometheus::Client::Push.new(@name, hostname, @url).add(@@registry)
40
- return { :case => :quiet_exit}
41
- end
42
43
 
43
44
 
44
- def call_and_notify(options)
45
- log = get_logger
46
- session = (options[:session])? options[:session] : get_session
47
- acase = { :case => :quiet_exit }
48
- exit_code = 0
49
- if @config.commands[@name.to_sym][:delegate_to] then
50
- return { :case => :options_incompatibility, :more => '--hostname forbidden with delagate commands'} if options[:hostname]
51
- log.send "Remote command : #{@name} execution delegate to : #{@config.commands[@name.to_sym][:delegate_to][:host]} as : #{@config.commands[@name.to_sym][:delegate_to][:remote_command]}", session
52
- begin
53
- transport = get_default_client
54
- if transport.class == Hash and transport.include? :case then
55
- return transport
56
- else
57
- res = transport.execute({ :verb => :execute_command,
58
- payload: {:name => @config.commands[@name.to_sym][:delegate_to][:remote_command].to_s},
59
- :return_to => "splash.#{Socket.gethostname}.return",
60
- :queue => "splash.#{@config.commands[@name.to_sym][:delegate_to][:host]}.input" })
61
- exit_code = res[:exit_code]
62
- log.receive "return with exitcode #{exit_code}", session
45
+ def call_and_notify(options)
46
+ log = get_logger
47
+ session = (options[:session])? options[:session] : get_session
48
+ acase = { :case => :quiet_exit }
49
+ exit_code = 0
50
+ if @config.commands[@name.to_sym][:delegate_to] then
51
+ return { :case => :options_incompatibility, :more => '--hostname forbidden with delagate commands'} if options[:hostname]
52
+ log.send "Remote command : #{@name} execution delegate to : #{@config.commands[@name.to_sym][:delegate_to][:host]} as : #{@config.commands[@name.to_sym][:delegate_to][:remote_command]}", session
53
+ begin
54
+ transport = get_default_client
55
+ if transport.class == Hash and transport.include? :case then
56
+ return transport
57
+ else
58
+ res = transport.execute({ :verb => :execute_command,
59
+ payload: {:name => @config.commands[@name.to_sym][:delegate_to][:remote_command].to_s},
60
+ :return_to => "splash.#{Socket.gethostname}.return",
61
+ :queue => "splash.#{@config.commands[@name.to_sym][:delegate_to][:host]}.input" })
62
+ exit_code = res[:exit_code]
63
+ log.receive "return with exitcode #{exit_code}", session
63
64
 
65
+ end
64
66
  end
65
- end
66
- else
67
- log.info "Executing command : '#{@name}' ", session
68
- start = Time.now
69
- start_date = DateTime.now.to_s
70
- unless options[:trace] then
71
- log.item "Traceless execution", session
72
- if @config.commands[@name.to_sym][:user] then
73
- log.item "Execute with user : #{@config.commands[@name.to_sym][:user]}.", session
74
- system("sudo -u #{@config.commands[@name.to_sym][:user]} #{@config.commands[@name.to_sym][:command]} > /dev/null 2>&1")
67
+ else
68
+ log.info "Executing command : '#{@name}' ", session
69
+ start = Time.now
70
+ start_date = DateTime.now.to_s
71
+ unless options[:trace] then
72
+ log.item "Traceless execution", session
73
+ if @config.commands[@name.to_sym][:user] then
74
+ log.item "Execute with user : #{@config.commands[@name.to_sym][:user]}.", session
75
+ system("sudo -u #{@config.commands[@name.to_sym][:user]} #{@config.commands[@name.to_sym][:command]} > /dev/null 2>&1")
76
+ else
77
+ system("#{@config.commands[@name.to_sym][:command]} > /dev/null 2>&1")
78
+ end
79
+ time = Time.now - start
80
+ exit_code = $?.exitstatus
75
81
  else
76
- system("#{@config.commands[@name.to_sym][:command]} > /dev/null 2>&1")
82
+ log.item "Tracefull execution", session
83
+ if @config.commands[@name.to_sym][:user] then
84
+ log.item "Execute with user : #{@config.commands[@name.to_sym][:user]}.", session
85
+ stdout, stderr, status = Open3.capture3("sudo -u #{@config.commands[@name.to_sym][:user]} #{@config.commands[@name.to_sym][:command]}")
86
+ else
87
+ stdout, stderr, status = Open3.capture3(@config.commands[@name.to_sym][:command])
88
+ end
89
+ time = Time.now - start
90
+ tp = Template::new(
91
+ list_token: @config.execution_template_tokens,
92
+ template_file: @config.execution_template_path)
93
+ data = Hash::new
94
+ data[:start_date] = start_date
95
+ data[:end_date] = DateTime.now.to_s
96
+ data[:cmd_name] = @name
97
+ data[:cmd_line] = @config.commands[@name.to_sym][:command]
98
+ data[:desc] = @config.commands[@name.to_sym][:desc]
99
+ data[:status] = status.to_s
100
+ data[:stdout] = stdout
101
+ data[:stderr] = stderr
102
+ data[:exec_time] = time.to_s
103
+ backend = get_backend :execution_trace
104
+ key = @name
105
+
106
+ backend.put key: key, value: data.to_yaml
107
+ exit_code = status.exitstatus
77
108
  end
78
- time = Time.now - start
79
- exit_code = $?.exitstatus
80
- else
81
- log.item "Tracefull execution", session
82
- if @config.commands[@name.to_sym][:user] then
83
- log.item "Execute with user : #{@config.commands[@name.to_sym][:user]}.", session
84
- stdout, stderr, status = Open3.capture3("sudo -u #{@config.commands[@name.to_sym][:user]} #{@config.commands[@name.to_sym][:command]}")
109
+ log.ok "Command executed", session
110
+ log.arrow "exitcode #{exit_code}", session
111
+ if options[:notify] then
112
+ acase = notify(exit_code,time.to_i)
113
+ get_logger.ok "Prometheus Gateway notified.",session
85
114
  else
86
- stdout, stderr, status = Open3.capture3(@config.commands[@name.to_sym][:command])
115
+ log.item "Without Prometheus notification", session
87
116
  end
88
- time = Time.now - start
89
- tp = Template::new(
90
- list_token: @config.execution_template_tokens,
91
- template_file: @config.execution_template_path)
92
- data = Hash::new
93
- data[:start_date] = start_date
94
- data[:end_date] = DateTime.now.to_s
95
- data[:cmd_name] = @name
96
- data[:cmd_line] = @config.commands[@name.to_sym][:command]
97
- data[:desc] = @config.commands[@name.to_sym][:desc]
98
- data[:status] = status.to_s
99
- data[:stdout] = stdout
100
- data[:stderr] = stderr
101
- data[:exec_time] = time.to_s
102
- backend = get_backend :execution_trace
103
- key = @name
104
-
105
- backend.put key: key, value: data.to_yaml
106
- exit_code = status.exitstatus
107
117
  end
108
- log.ok "Command executed", session
109
- log.arrow "exitcode #{exit_code}", session
110
- if options[:notify] then
111
- acase = notify(exit_code,time.to_i)
112
- get_logger.ok "Prometheus Gateway notified.",session
113
- else
114
- log.item "Without Prometheus notification", session
115
- end
116
- end
117
118
 
118
- if options[:callback] then
119
- on_failure = (@config.commands[@name.to_sym][:on_failure])? @config.commands[@name.to_sym][:on_failure] : false
120
- on_success = (@config.commands[@name.to_sym][:on_success])? @config.commands[@name.to_sym][:on_success] : false
121
- if on_failure and exit_code > 0 then
122
- log.item "On failure callback : #{on_failure}", session
123
- if @config.commands.keys.include? on_failure then
124
- @name = on_failure.to_s
125
- call_and_notify options
126
- else
127
- acase = { :case => :configuration_error , :more => "on_failure call error : #{on_failure} command inexistant."}
119
+ if options[:callback] then
120
+ on_failure = (@config.commands[@name.to_sym][:on_failure])? @config.commands[@name.to_sym][:on_failure] : false
121
+ on_success = (@config.commands[@name.to_sym][:on_success])? @config.commands[@name.to_sym][:on_success] : false
122
+ if on_failure and exit_code > 0 then
123
+ log.item "On failure callback : #{on_failure}", session
124
+ if @config.commands.keys.include? on_failure then
125
+ @name = on_failure.to_s
126
+ call_and_notify options
127
+ else
128
+ acase = { :case => :configuration_error , :more => "on_failure call error : #{on_failure} command inexistant."}
129
+ end
128
130
  end
129
- end
130
- if on_success and exit_code == 0 then
131
- log.item "On success callback : #{on_success}", session
132
- if @config.commands.keys.include? on_success then
133
- @name = on_success.to_s
134
- call_and_notify options
135
- else
136
- acase = { :case => :configuration_error , :more => "on_success call error : #{on_failure} command inexistant."}
131
+ if on_success and exit_code == 0 then
132
+ log.item "On success callback : #{on_success}", session
133
+ if @config.commands.keys.include? on_success then
134
+ @name = on_success.to_s
135
+ call_and_notify options
136
+ else
137
+ acase = { :case => :configuration_error , :more => "on_success call error : #{on_failure} command inexistant."}
138
+ end
137
139
  end
140
+ else
141
+ log.item "Without callbacks sequences", session
138
142
  end
139
- else
140
- log.item "Without callbacks sequences", session
143
+ acase[:exit_code] = exit_code
144
+ return acase
141
145
  end
142
- acase[:exit_code] = exit_code
143
- return acase
144
146
  end
145
147
  end
146
148
  end