prometheus-splash 0.4.5 → 0.5.0

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: 7f4ea7ed10be999a00e43e04651616be5db143bbc0d85c11a1ca7126ad68aa33
4
- data.tar.gz: dd66e18d9c1633033142b94852f3af61b066dd3dbc80de451f733b379e797203
3
+ metadata.gz: d510e4761e365c1ee36881fb1a3a4a99a7dbe7965958841497cdcaaadfb0c1b3
4
+ data.tar.gz: 4f01f486135696ef0142d42362379e59868b1265ce367b3e3aac9853fcc48336
5
5
  SHA512:
6
- metadata.gz: d923826528d62549cf890121e20474d13e5b88e1d8da3e8bf3136ef3232dd4a92b0bf11a6b4d07817786f192dc7e50e6f018d0611e544fafd906d7b7f8e9f79d
7
- data.tar.gz: 3fec4f6263749824d308f1bbbeabf7dbd7ab5bef5f025ec921f0cef0f2ebd0b32584a117550091344b26dcf257cf0ed10fb7d6dbfd887ff8502468595d5ca578
6
+ metadata.gz: 8b5c84b54b2098f9b027408ab8419fb19964feb1056607d090802acc793c2ccd6a9b98c1c8c2ca91334ccc8a36de88c1bf6cd674b6f5ef9df33a40debbfe84f5
7
+ data.tar.gz: 1d93b819d8a9592495271a24bdc3e69e63a15489f5885faa729a8e42428a68dada73748ea8440c1338625a36c89d84a260e3bc9cdafa8fb869747864edc001f4
data/CHANGELOG.md CHANGED
@@ -12,14 +12,14 @@
12
12
  * adding \n for LONGDESC Thor #14
13
13
  * Doc for command name format in YAML #2
14
14
 
15
- ### CHANGE :
15
+ ### CHANGES :
16
16
 
17
17
  * RabbitMQ Credentials and vhosts support #16
18
18
  * backend hardening #18
19
19
  * remote show with --hostname #12
20
20
 
21
21
 
22
- ### FEATURE :
22
+ ### FEATURES :
23
23
 
24
24
  * CLI colors and logger CLI /dual #8
25
25
  * Log for splash daemon #6
@@ -63,3 +63,21 @@
63
63
  ### FIX :
64
64
 
65
65
  * RabbitMQ Exception catching + refacto connection #31
66
+
67
+
68
+ ## V 0.5.0 2020/04/17
69
+
70
+ ### FIX
71
+
72
+ * auto setup root check without /etc/splash.yml #34
73
+ * empty hostname with --hostname #27
74
+ * foreground execution control #24
75
+ * root required for file backend with command last and get #36
76
+
77
+ ### FEATURES
78
+
79
+ * command treeview with --hostname #28
80
+ * log horodating with PID #35
81
+ * quiet mode + no-colors and no-emoji #5
82
+ * correlation id in log for daemon #15
83
+ * systemd Splashd service installation #32
data/bin/splash CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby
1
+ #!/usr/bin/env ruby
2
2
  # coding: utf-8
3
3
 
4
4
  require 'splash/dependencies'
@@ -14,11 +14,16 @@ include Splash::Loggers
14
14
  include Splash::Config
15
15
 
16
16
  unless verify_file(name: CONFIG_FILE, mode: "644", owner: user_root, group: group_root).empty? then
17
- puts 'ERROR: Splash need reconfiguration : execution abort, '
18
- puts ' => Restart after rebuild (recheck for homemade templates) :'
17
+ puts 'Splash need reconfiguration : Auto setup launch'
19
18
 
20
- acase = run_as_root :setupsplash
21
- splash_exit acase
19
+ if is_root? then
20
+ acase = setupsplash
21
+ splash_exit acase
22
+ else
23
+ puts 'ERROR : auto setup not start, because your not root, please run as root :'
24
+ puts '(sudo or rvmsudo) splash [conf setup]'
25
+ exit 50
26
+ end
22
27
  end
23
28
 
24
29
  CLI.start(ARGV)
@@ -27,8 +27,10 @@ module CLISplash
27
27
  option :hostname, :type => :string
28
28
  def execute(name)
29
29
  log = get_logger
30
+ log.level = :fatal if options[:quiet]
30
31
  if is_root? then
31
32
  if options[:hostname] then
33
+ options[:hostname] = Socket.gethostname if options[:hostname] == 'hostname'
32
34
  splash_exit({ :case => :options_incompatibility, :more => '--hostname forbidden with delagate commands'}) if get_config.commands[name.to_sym][:delegate_to]
33
35
  log.info "Remote Splash configured commands on #{options[:hostname]}:"
34
36
  log.info "ctrl+c for interrupt"
@@ -49,13 +51,14 @@ module CLISplash
49
51
  payload: {:name => name},
50
52
  :return_to => "splash.#{Socket.gethostname}.returncli",
51
53
  :queue => "splash.#{options[:hostname]}.input" })
52
- res[:more] = "Remote command : :execute_command Scheduled"
53
- splash_exit res
54
54
  end
55
55
  end
56
56
  rescue Interrupt
57
57
  splash_exit case: :interrupt, more: "Remote command exection"
58
58
  end
59
+ log.receive "Command execute confirmation"
60
+ res[:more] = "Remote command : :execute_command Scheduled"
61
+ splash_exit res
59
62
  else
60
63
  command = Splash::CommandWrapper::new(name)
61
64
  if options[:ack] then
@@ -80,11 +83,12 @@ module CLISplash
80
83
  WARNING : scheduling by CLI are not percisted, so use it only for specifics cases.\n
81
84
  NOTES : Scheduling, force trace, notifying and callback.
82
85
  LONGDESC
83
- option :hostname, :type => :string
86
+ option :hostname, :type => :string, :default => Socket.gethostname
84
87
  option :at, :type => :string
85
88
  option :in, :type => :string
86
89
  def schedule(name)
87
90
  log = get_logger
91
+ log.level = :fatal if options[:quiet]
88
92
  hostname = (options[:hostname])? options[:hostname] : Socket.gethostname
89
93
  splash_exit({ :case => :options_incompatibility, :more => '--at or --in is required'}) unless options[:at] or options[:in]
90
94
  splash_exit({ :case => :options_incompatibility, :more => '--at an --in'}) if options[:at] and options[:in]
@@ -101,32 +105,61 @@ module CLISplash
101
105
  payload: {:name => name, :schedule => schedule},
102
106
  :return_to => "splash.#{Socket.gethostname}.returncli",
103
107
  :queue => "splash.#{hostname}.input" })
104
- log.receive "Execute command sheduled confirmed"
105
- res[:more] = "Remote command : :execute_command with schedule"
106
- splash_exit res
107
108
  end
108
109
  rescue Interrupt
109
110
  splash_exit case: :interrupt, more: "Remote command exection"
110
111
  end
112
+ log.receive "Execute command sheduled confirmed"
113
+ res[:more] = "Remote command : :execute_command with schedule"
114
+ splash_exit res
111
115
 
112
116
  end
113
117
 
114
118
 
115
119
  desc "treeview", "Show commands sequence tree"
116
- def treeview(command, depht = 0)
120
+ long_desc <<-LONGDESC
121
+ Show commands sequence tree\n
122
+ with --hostname, ask other Splash daemon via transport\n
123
+ LONGDESC
124
+ option :hostname, :type => :string
125
+ def treeview(command)
126
+ depht = 0
117
127
  log = get_logger
118
- log.info "Command : #{command.to_s}" if depht == 0
119
- cmd = get_config.commands[command.to_sym]
120
- if cmd[:on_failure] then
121
- spacer= " " * depht + " "
122
- log.flat "#{spacer}* on failure => #{cmd[:on_failure]}"
123
- treeview(cmd[:on_failure], depht+2)
128
+ if options[:hostname] then
129
+ options[:hostname] = Socket.gethostname if options[:hostname] == 'hostname'
130
+ log.info "Remote Splash scheduling command on #{options[:hostname]}:"
131
+ log.info "ctrl+c for interrupt"
132
+ begin
133
+ transport = get_default_client
134
+ if transport.class == Hash and transport.include? :case then
135
+ splash_exit transport
136
+ else
137
+ commands = transport.execute({ :verb => :list_commands,
138
+ :return_to => "splash.#{Socket.gethostname}.returncli",
139
+ :queue => "splash.#{options[:hostname]}.input" })
140
+ end
141
+ rescue Interrupt
142
+ splash_exit case: :interrupt, more: "Remote command exection"
143
+ end
144
+ log.receive "Receving list of commands from #{options[:hostname]}"
145
+ else
146
+ commands = get_config.commands
124
147
  end
125
- if cmd[:on_success] then
126
- spacer = " " * depht + " "
127
- log.flat "#{spacer}* on success => #{cmd[:on_success]}"
128
- treeview(cmd[:on_success],depht+2)
148
+ log.info "Command : #{command.to_s}" if depht == 0
149
+ aproc = Proc::new do |command,depht|
150
+ cmd = commands[command.to_sym]
151
+ if cmd[:on_failure] then
152
+ spacer= " " * depht + " "
153
+ log.flat "#{spacer}* on failure => #{cmd[:on_failure]}"
154
+ aproc.call(cmd[:on_failure], depht+2)
155
+ end
156
+ if cmd[:on_success] then
157
+ spacer = " " * depht + " "
158
+ log.flat "#{spacer}* on success => #{cmd[:on_success]}"
159
+ aproc.call(cmd[:on_success],depht+2)
160
+ end
129
161
  end
162
+ aproc.call(command,depht)
130
163
  end
131
164
 
132
165
 
@@ -142,6 +175,7 @@ module CLISplash
142
175
  log = get_logger
143
176
  list = {}
144
177
  if options[:hostname] then
178
+ options[:hostname] = Socket.gethostname if options[:hostname] == 'hostname'
145
179
  log.info "Remote Splash configured commands on #{options[:hostname]}:"
146
180
  log.info "ctrl+c for interrupt"
147
181
  begin
@@ -156,10 +190,11 @@ module CLISplash
156
190
  rescue Interrupt
157
191
  splash_exit case: :interrupt, more: "remote list Command"
158
192
  end
193
+ log.receive "Receving list of commands from #{options[:hostname]}"
159
194
  else
160
- log.info "Splash configured commands :"
161
195
  list = get_config.commands
162
196
  end
197
+ log.info "Splash configured commands :"
163
198
  log.ko 'No configured commands found' if list.keys.empty?
164
199
  list.keys.each do |command|
165
200
  log.item "#{command.to_s}"
@@ -188,6 +223,7 @@ module CLISplash
188
223
  log = get_logger
189
224
  list = {}
190
225
  if options[:hostname] then
226
+ options[:hostname] = Socket.gethostname if options[:hostname] == 'hostname'
191
227
  log.info "Remote Splash configured commands on #{options[:hostname]}:"
192
228
  log.info "ctrl+c for interrupt"
193
229
  begin
@@ -202,6 +238,7 @@ module CLISplash
202
238
  rescue Interrupt
203
239
  splash_exit case: :interrupt, more: "remote list Command"
204
240
  end
241
+ log.receive "Receving list of commands from #{options[:hostname]}"
205
242
  else
206
243
  list = get_config.commands
207
244
  end
@@ -235,8 +272,10 @@ module CLISplash
235
272
  if not redis and options[:hostname] then
236
273
  splash_exit case: :specific_config_required, :more => "Redis backend is requiered for Remote execution report request"
237
274
  end
275
+ splash_exit case: :not_root if not is_root? and not redis
238
276
  list = get_config.commands.keys
239
277
  if options[:hostname] then
278
+ options[:hostname] = Socket.gethostname if options[:hostname] == 'hostname'
240
279
  list = backend.list("*", options[:hostname]).map(&:to_sym)
241
280
  end
242
281
  if list.include? command.to_sym then
@@ -274,6 +313,7 @@ module CLISplash
274
313
  option :detail, :type => :boolean
275
314
  def getreportlist
276
315
  log = get_logger
316
+ options[:hostname] = Socket.gethostname if options[:hostname] == 'hostname'
277
317
  if options[:hostname] and options[:all] then
278
318
  splash_exit case: :options_incompatibility, more: "--all, --hostname"
279
319
  end
@@ -282,6 +322,7 @@ module CLISplash
282
322
  if not redis and (options[:hostname] or options[:all]) then
283
323
  splash_exit case: :specific_config_required, more: "Redis Backend requiered for Remote execution report Request"
284
324
  end
325
+ splash_exit case: :not_root if not is_root? and not redis
285
326
  pattern = (options[:pattern])? options[:pattern] : '*'
286
327
  if options[:all] then
287
328
  res = backend.listall pattern
@@ -25,15 +25,22 @@ module CLISplash
25
25
  splash_exit acase
26
26
  end
27
27
 
28
- desc "version", "display current Splash version"
28
+ desc "version", "Display current Splash version"
29
29
  def version
30
30
  log = get_logger
31
31
  config = get_config
32
32
  log.info "Splash version : #{config.version}, Author : #{config.author}"
33
- log_info config.copyright
33
+ log.info config.copyright
34
34
  splash_exit case: :quiet_exit
35
35
  end
36
36
 
37
+ desc "service", "Install Splashd Systemd service"
38
+ def service
39
+ acase = run_as_root :addservice
40
+ splash_exit acase
41
+ end
42
+
43
+
37
44
  end
38
45
 
39
46
  end
@@ -19,17 +19,6 @@ module CLISplash
19
19
  LONGDESC
20
20
  desc "start", "Starting Splash Daemon"
21
21
  def start
22
- log = get_logger
23
- if options[:purge] then
24
- transport = get_default_client
25
- if transport.class == Hash and transport.include? :case then
26
- splash_exit transport
27
- else
28
- queue = "splash.#{Socket.gethostname}.input"
29
- transport.purge queue: queue
30
- log.info "Queue : #{queue} purged"
31
- end
32
- end
33
22
  acase = run_as_root :startdaemon, options
34
23
  splash_exit acase
35
24
  end
@@ -38,6 +27,7 @@ module CLISplash
38
27
  desc "purge", "Purge Transport Input queue of Daemon"
39
28
  def purge
40
29
  log = get_logger
30
+ log.level = :fatal if options[:quiet]
41
31
  transport = get_default_client
42
32
  if transport.class == Hash and transport.include? :case then
43
33
  splash_exit transport
@@ -40,9 +40,10 @@ module CLISplash
40
40
 
41
41
  desc "monitor", "monitor logs in config"
42
42
  def monitor
43
+ log = get_logger
44
+ log.level = :fatal if options[:quiet]
43
45
  result = Splash::LogScanner::new
44
46
  result.analyse
45
- result.notify
46
47
  splash_exit result.notify
47
48
 
48
49
  end
data/lib/splash/cli.rb CHANGED
@@ -6,6 +6,21 @@ class CLI < Thor
6
6
  true
7
7
  end
8
8
 
9
+
10
+ def initialize(*args)
11
+ super
12
+ log = get_logger
13
+ options[:colors.to_s]
14
+ log.emoji = options[:emoji.to_s]
15
+ log.color = options[:colors.to_s]
16
+ end
17
+
18
+ class_option :quiet, :desc => "Quiet mode, limit output to :fatal", :aliases => "-q", :type => :boolean
19
+ class_option :emoji, :desc => "Display Emoji", :type => :boolean, :default => true
20
+ class_option :colors, :desc => "Display colors", :type => :boolean, :default => true
21
+
22
+
23
+
9
24
  include CLISplash
10
25
  desc "commands SUBCOMMAND ...ARGS", "Managing commands/batchs supervision"
11
26
  subcommand "commands", Commands
@@ -37,18 +37,18 @@ module Splash
37
37
  @@metric_time.set(time)
38
38
  hostname = Socket.gethostname
39
39
  Prometheus::Client::Push.new(@name, hostname, @url).add(@@registry)
40
- get_logger.ok "Prometheus Gateway notified."
41
40
  return { :case => :quiet_exit}
42
41
  end
43
42
 
44
43
 
45
44
  def call_and_notify(options)
46
45
  log = get_logger
46
+ session = (options[:session])? options[:session] : get_session
47
47
  acase = { :case => :quiet_exit }
48
48
  exit_code = 0
49
49
  if @config.commands[@name.to_sym][:delegate_to] then
50
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]}"
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
52
  begin
53
53
  transport = get_default_client
54
54
  if transport.class == Hash and transport.include? :case then
@@ -59,18 +59,18 @@ module Splash
59
59
  :return_to => "splash.#{Socket.gethostname}.return",
60
60
  :queue => "splash.#{@config.commands[@name.to_sym][:delegate_to][:host]}.input" })
61
61
  exit_code = res[:exit_code]
62
- log.receive "return with exitcode #{exit_code}"
62
+ log.receive "return with exitcode #{exit_code}", session
63
63
 
64
64
  end
65
65
  end
66
66
  else
67
- log.info "Executing command : '#{@name}' "
67
+ log.info "Executing command : '#{@name}' ", session
68
68
  start = Time.now
69
69
  start_date = DateTime.now.to_s
70
70
  unless options[:trace] then
71
- log.item "Traceless execution"
71
+ log.item "Traceless execution", session
72
72
  if @config.commands[@name.to_sym][:user] then
73
- log.item "Execute with user : #{@config.commands[@name.to_sym][:user]}."
73
+ log.item "Execute with user : #{@config.commands[@name.to_sym][:user]}.", session
74
74
  system("sudo -u #{@config.commands[@name.to_sym][:user]} #{@config.commands[@name.to_sym][:command]} > /dev/null 2>&1")
75
75
  else
76
76
  system("#{@config.commands[@name.to_sym][:command]} > /dev/null 2>&1")
@@ -78,9 +78,9 @@ module Splash
78
78
  time = Time.now - start
79
79
  exit_code = $?.exitstatus
80
80
  else
81
- log.item "Tracefull execution"
81
+ log.item "Tracefull execution", session
82
82
  if @config.commands[@name.to_sym][:user] then
83
- log.item "Execute with user : #{@config.commands[@name.to_sym][:user]}."
83
+ log.item "Execute with user : #{@config.commands[@name.to_sym][:user]}.", session
84
84
  stdout, stderr, status = Open3.capture3("sudo -u #{@config.commands[@name.to_sym][:user]} #{@config.commands[@name.to_sym][:command]}")
85
85
  else
86
86
  stdout, stderr, status = Open3.capture3(@config.commands[@name.to_sym][:command])
@@ -101,15 +101,17 @@ module Splash
101
101
  data[:exec_time] = time.to_s
102
102
  backend = get_backend :execution_trace
103
103
  key = @name
104
+
104
105
  backend.put key: key, value: data.to_yaml
105
106
  exit_code = status.exitstatus
106
107
  end
107
- log.ok "Command executed"
108
- log.arrow "exitcode #{exit_code}"
108
+ log.ok "Command executed", session
109
+ log.arrow "exitcode #{exit_code}", session
109
110
  if options[:notify] then
110
111
  acase = notify(exit_code,time.to_i)
112
+ get_logger.ok "Prometheus Gateway notified.",session
111
113
  else
112
- log.item "Without Prometheus notification"
114
+ log.item "Without Prometheus notification", session
113
115
  end
114
116
  end
115
117
 
@@ -117,7 +119,7 @@ module Splash
117
119
  on_failure = (@config.commands[@name.to_sym][:on_failure])? @config.commands[@name.to_sym][:on_failure] : false
118
120
  on_success = (@config.commands[@name.to_sym][:on_success])? @config.commands[@name.to_sym][:on_success] : false
119
121
  if on_failure and exit_code > 0 then
120
- log.item "On failure callback : #{on_failure}"
122
+ log.item "On failure callback : #{on_failure}", session
121
123
  if @config.commands.keys.include? on_failure then
122
124
  @name = on_failure.to_s
123
125
  call_and_notify options
@@ -126,7 +128,7 @@ module Splash
126
128
  end
127
129
  end
128
130
  if on_success and exit_code == 0 then
129
- log.item "On success callback : #{on_success}"
131
+ log.item "On success callback : #{on_success}", session
130
132
  if @config.commands.keys.include? on_success then
131
133
  @name = on_success.to_s
132
134
  call_and_notify options
@@ -135,7 +137,7 @@ module Splash
135
137
  end
136
138
  end
137
139
  else
138
- log.item "Without callbacks sequences"
140
+ log.item "Without callbacks sequences", session
139
141
  end
140
142
  acase[:exit_code] = exit_code
141
143
  return acase
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+
3
+
4
+ module Splash
5
+ module ConfigUtilities
6
+ include Splash::Constants
7
+ include Splash::Helpers
8
+
9
+ def addservice(options = {})
10
+ local_service_file = search_file_in_gem "prometheus-splash", "templates/splashd.service"
11
+ config = get_config
12
+ self.extend Splash::Loggers
13
+ log = get_logger
14
+ log.info "Splashd Systemd Service installation"
15
+ service_file = "splashd.service"
16
+ systemd_path = "/etc/systemd/system"
17
+ return { :case => :options_incompatibility, :more => "Systemd not avaible on this System" } if verify_folder({ :name => systemd_path}) == [:inexistant]
18
+ log.item "Installing service file : #{service_file} in #{systemd_path}"
19
+ if install_file source: local_service_file, target: "#{systemd_path}/#{service_file}", mode: "755", owner: config.user_root, group: config.group_root then
20
+ return { :case => :quiet_exit, :more => "Splashd Systemd service installed" }
21
+ else
22
+ return { :case => :error_exit, :more => "Splashd Systemd service could not be installed" }
23
+ end
24
+ end
25
+ end
26
+ end
data/lib/splash/config.rb CHANGED
@@ -115,11 +115,14 @@ module Splash
115
115
 
116
116
  end
117
117
 
118
+
119
+
120
+ @@config=nil
118
121
  # factory of Configuration Class instance
119
122
  # @param [String] config_file the path of the YAML Config file
120
123
  # @return [SPlash::Config::Configuration]
121
124
  def get_config(config_file=CONFIG_FILE)
122
- return Configuration::new config_file
125
+ return @@config ||= Configuration::new(config_file)
123
126
  end
124
127
 
125
128
 
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
  module Splash
3
3
  module Constants
4
- VERSION = "0.4.5"
4
+ VERSION = "0.5.0"
5
5
 
6
6
  # the path to th config file, not overridable by config
7
7
  CONFIG_FILE = "/etc/splash.yml"
@@ -12,10 +12,30 @@ module Splash
12
12
  def startdaemon(options = {})
13
13
  config = get_config
14
14
  log = get_logger
15
+ log.level = :fatal if options[:quiet]
15
16
  unless verify_service host: config.prometheus_pushgateway_host ,port: config.prometheus_pushgateway_port then
16
17
  return {:case => :service_dependence_missing, :more => 'Prometheus Gateway'}
17
18
  end
19
+ realpid = get_processes pattern: get_config.daemon_process_name
20
+ foreground = get_processes patterns: [ "splash", "foreground" ]
21
+ unless foreground.empty? or options[:foreground] then
22
+ return {:case => :already_exist, :more => "Splash Process already launched on foreground "}
23
+ end
24
+
18
25
  unless File::exist? config.full_pid_path then
26
+ unless realpid.empty? then
27
+ return {:case => :already_exist, :more => "Splash Process already launched "}
28
+ end
29
+ if options[:purge] then
30
+ transport = get_default_client
31
+ if transport.class == Hash and transport.include? :case then
32
+ splash_exit transport
33
+ else
34
+ queue = "splash.#{Socket.gethostname}.input"
35
+ transport.purge queue: queue
36
+ log.info "Queue : #{queue} purged"
37
+ end
38
+ end
19
39
  daemon_config = {:description => config.daemon_process_name,
20
40
  :pid_file => config.full_pid_path,
21
41
  :stdout_trace => config.full_stdout_trace_path,
@@ -43,6 +63,8 @@ module Splash
43
63
 
44
64
  def stopdaemon(options = {})
45
65
  config = get_config
66
+ log = get_logger
67
+ log.level = :fatal if options[:quiet]
46
68
  if File.exist?(config.full_pid_path) then
47
69
  begin
48
70
  pid = `cat #{config.full_pid_path}`.to_i
@@ -63,9 +85,13 @@ module Splash
63
85
  config = get_config
64
86
  pid = realpid = ''
65
87
  pid = `cat #{config.full_pid_path}`.to_s if File.exist?(config.full_pid_path)
66
- realpid = get_process pattern: get_config.daemon_process_name
88
+ listpid = get_processes({ :pattern => get_config.daemon_process_name})
67
89
  pid.chomp!
68
- realpid.chomp!
90
+ if listpid.empty? then
91
+ realpid = ''
92
+ else
93
+ realpid = listpid.first
94
+ end
69
95
  unless realpid.empty? then
70
96
  log.item "Splash Process is running with PID #{realpid} "
71
97
  else
@@ -26,6 +26,7 @@ module Splash
26
26
  require 'tty-pager'
27
27
  require 'colorize'
28
28
  require "redis"
29
+ require 'ps-ruby'
29
30
 
30
31
  rescue Gem::GemNotFoundException
31
32
  $stderr.puts "Loadind error, it's like you try to run Splash, with a lake of dependencies."
data/lib/splash/exiter.rb CHANGED
@@ -20,6 +20,7 @@ module Splash
20
20
 
21
21
  # global
22
22
  :quiet_exit => {:code => 0},
23
+ :error_exit => {:code => 99, :message => "Operation failure"},
23
24
 
24
25
  # events
25
26
  :interrupt => {:message => "Splash user operation interrupted", :code => 33},
@@ -13,18 +13,20 @@ module Splash
13
13
  return Etc.getgrgid(0).name
14
14
  end
15
15
 
16
- # facilité pour récupérer un PID depuis une regexp
16
+ # facilité pour récupérer les PID depuis une regexp
17
17
  # @param [Hash] options
18
- # @option options [String] :pattern une regexp
18
+ # @option options [String] :pattern un motif de regexp
19
+ # @option options [Array] :patterns Un tableau de motif de regexp
19
20
  # @return [String] le PID
20
- def get_process(options = {})
21
- pattern = options[:pattern]
22
- res = `ps aux|grep '#{pattern}'|grep -v grep`.to_s
23
- unless res.empty? then
24
- return res.split(/\s+/)[1]
25
- else
26
- return ''
21
+ def get_processes(options = {})
22
+ patterns = []
23
+ patterns = options[:patterns] if options[:patterns]
24
+ patterns << options[:pattern] if options[:pattern]
25
+ res = PS.get_all_processes
26
+ patterns.each do |item|
27
+ res = res.find_processes item
27
28
  end
29
+ return res.pick_attr('PID')
28
30
  end
29
31
 
30
32
 
@@ -156,7 +158,10 @@ module Splash
156
158
  }
157
159
  if options[:foreground]
158
160
  change_logger logger: :dual
161
+ Process.setproctitle options[:description] if options[:description]
162
+ p $0
159
163
  return yield
164
+ p 'titi'
160
165
  end
161
166
  fork do
162
167
  change_logger logger: :daemon
@@ -16,9 +16,15 @@ module Splash
16
16
 
17
17
 
18
18
  def log(options)
19
+ pid = Process.pid.to_s
20
+ date = DateTime.now.to_s
19
21
  level = (ALIAS.keys.include? options[:level])? ALIAS[options[:level]] : options[:level]
20
22
  if @active_levels.include? level then
21
- @stream.puts "#{alt(options[:level])} #{options[:message]}"
23
+ unless options[:session].empty? then
24
+ @stream.puts "[#{date}] (#{pid}) (#{options[:session]}) #{alt(options[:level])} : #{options[:message]}"
25
+ else
26
+ @stream.puts "[#{date}] (#{pid}) #{alt(options[:level])} : #{options[:message]}"
27
+ end
22
28
  end
23
29
  end
24
30
 
@@ -26,6 +32,8 @@ module Splash
26
32
  @stream.close
27
33
  end
28
34
 
35
+
36
+
29
37
  end
30
38
 
31
39
  end
@@ -18,6 +18,10 @@ module Splash
18
18
  # end
19
19
  end
20
20
 
21
+ def get_session
22
+ return "#{Time.now.to_i.to_s}#{rand(999)}"
23
+ end
24
+
21
25
 
22
26
  def change_logger(options = {})
23
27
  options[:force] = true
@@ -34,13 +38,13 @@ module Splash
34
38
  :schedule => :info, :arrow => :info, :send => :info,
35
39
  :receive => :info, :error => :result, :success => :result }
36
40
  LEVELS.each do |method|
37
- define_method(method) do |message|
38
- self.log({ :level => method, :message => message})
41
+ define_method(method) do |message,session = ''|
42
+ self.log({ :level => method, :message => message, :session => session})
39
43
  end
40
44
  end
41
45
  ALIAS.keys.each do |method|
42
- define_method(method) do |message|
43
- self.log({ :level => method, :message => message})
46
+ define_method(method) do |message,session = ''|
47
+ self.log({ :level => method, :message => message, :session => session})
44
48
  end
45
49
  end
46
50
  def initialize
data/lib/splash/logs.rb CHANGED
@@ -42,15 +42,16 @@ module Splash
42
42
  end
43
43
 
44
44
  # start notification on prometheus for metric logerrors, logmissing; loglines
45
- def notify
45
+ def notify(options = {})
46
46
  log = get_logger
47
47
  unless verify_service host: @config.prometheus_pushgateway_host ,port: @config.prometheus_pushgateway_port then
48
48
  return { :case => :service_dependence_missing, :more => "Prometheus Notification not send." }
49
49
  end
50
- log.info "Sending metrics to Prometheus Pushgateway"
50
+ session = (options[:session]) ? options[:session] : log.get_session
51
+ log.info "Sending metrics to Prometheus Pushgateway", session
51
52
  @logs_target.each do |item|
52
53
  missing = (item[:status] == :missing)? 1 : 0
53
- log.item "Sending metrics for #{item[:log]}"
54
+ log.item "Sending metrics for #{item[:log]}", session
54
55
  @metric_count.set(item[:count], labels: { log: item[:log] })
55
56
  @metric_missing.set(missing, labels: { log: item[:log] })
56
57
  lines = (item[:lines])? item[:lines] : 0
@@ -59,7 +60,7 @@ module Splash
59
60
  hostname = Socket.gethostname
60
61
  url = "http://#{@config.prometheus_pushgateway_host}:#{@config.prometheus_pushgateway_port}"
61
62
  Prometheus::Client::Push.new('Splash',hostname, url).add(@registry)
62
- log.ok "Sending to Prometheus PushGateway done."
63
+ log.ok "Sending to Prometheus PushGateway done.", session
63
64
  return {:case => :quiet_exit }
64
65
  end
65
66
 
@@ -14,36 +14,37 @@ module Splash
14
14
  terminate
15
15
  end
16
16
 
17
- def ping(payload)
18
- return "Pong : #{payload[:hostname]} !"
17
+ def ping(content)
18
+ return "Pong : #{content[:payload][:hostname]} !"
19
19
  end
20
20
 
21
21
 
22
- def list_commands
22
+ def list_commands(content)
23
23
  return get_config.commands
24
24
  end
25
25
 
26
- def ack_command(payload)
27
- return execute command: payload[:name], ack: true
26
+ def ack_command(content)
27
+ return execute command: content[:payload][:name], ack: true
28
28
  end
29
29
 
30
30
 
31
- def execute_command(payload)
31
+ def execute_command(content)
32
+ payload = content[:payload]
32
33
  unless get_config.commands.include? payload[:name].to_sym
33
- @log.item "Command not found"
34
+ @log.item "Command not found", content[:session]
34
35
  return { :case => :not_found }
35
36
  end
36
37
  if payload.include? :schedule then
37
38
  sched,value = payload[:schedule].flatten
38
- @log.schedule "remote call command #{payload[:name]}, scheduling : #{sched.to_s} #{value}"
39
+ @log.schedule "remote call command #{payload[:name]}, scheduling : #{sched.to_s} #{value}", content[:session]
39
40
  @server.send sched,value do
40
- @log.trigger "Executing Scheduled command #{payload[:name]} for Scheduling : #{sched.to_s} #{value}"
41
- execute command: payload[:name]
41
+ @log.trigger "Executing Scheduled command #{payload[:name]} for Scheduling : #{sched.to_s} #{value}", content[:session]
42
+ execute command: payload[:name], session: content[:session]
42
43
  end
43
44
  return { :case => :quiet_exit }
44
45
  else
45
- @log.info "Execute direct command"
46
- res = execute command: payload[:name]
46
+ @log.info "Execute direct command", content[:session]
47
+ res = execute command: payload[:name], session: content[:session]
47
48
  return res
48
49
  end
49
50
  end
@@ -31,11 +31,12 @@ module Splash
31
31
  @log.item "Initializing logs monitorings & notifications."
32
32
  @server.send sched,value do
33
33
  begin
34
- @log.trigger "Logs monitoring for Scheduling : #{sched.to_s} #{value.to_s}"
34
+ session = get_session
35
+ @log.trigger "Logs monitoring for Scheduling : #{sched.to_s} #{value.to_s}", session
35
36
  @result.analyse
36
- @result.notify
37
+ @result.notify :session => session
37
38
  rescue Errno::ECONNREFUSED
38
- @log.error "PushGateway seems to be done, please start it."
39
+ @log.error "PushGateway seems to be done, please start it.", session
39
40
  end
40
41
  end
41
42
  hostname = Socket.gethostname
@@ -45,17 +46,15 @@ module Splash
45
46
  end
46
47
  transport.subscribe(:block => true) do |delivery_info, properties, body|
47
48
  content = YAML::load(body)
49
+ session = get_session
50
+ content[:session] = session
48
51
  if VERBS.include? content[:verb]
49
- @log.receive "Valid remote order, verb : #{content[:verb].to_s}"
50
- if content[:payload] then
51
- res = self.send content[:verb], content[:payload]
52
- else
53
- res = self.send content[:verb]
54
- end
52
+ @log.receive "Valid remote order, verb : #{content[:verb].to_s}", session
53
+ res = self.send content[:verb], content
55
54
  get_default_client.publish queue: content[:return_to], message: res.to_yaml
56
- @log.send "Result to #{content[:return_to]}."
55
+ @log.send "Result to #{content[:return_to]}.", session
57
56
  else
58
- @log.receive "INVALID remote order, verb : #{content[:verb].to_s}"
57
+ @log.receive "INVALID remote order, verb : #{content[:verb].to_s}", session
59
58
  get_default_client.publish queue: content[:return_to], message: "Unkown verb #{content[:verb]}".to_yaml
60
59
  end
61
60
  end
@@ -76,8 +75,9 @@ module Splash
76
75
  sched,value = config[command][:schedule].flatten
77
76
  @log.arrow "Scheduling command #{command.to_s}"
78
77
  @server.send sched,value do
79
- @log.trigger "Executing Scheduled command #{command.to_s} for Scheduling : #{sched.to_s} #{value.to_s}"
80
- execute command: command.to_s
78
+ session = get_session
79
+ @log.trigger "Executing Scheduled command #{command.to_s} for Scheduling : #{sched.to_s} #{value.to_s}", session
80
+ execute command: command.to_s, session: session
81
81
  end
82
82
  end
83
83
 
@@ -88,7 +88,7 @@ module Splash
88
88
  if options[:ack] then
89
89
  command.ack
90
90
  else
91
- return command.call_and_notify trace: true, notify: true, callback: true
91
+ return command.call_and_notify trace: true, notify: true, callback: true, session: options[:session]
92
92
  end
93
93
  end
94
94
 
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.add_runtime_dependency 'rufus-scheduler','~> 3.6.0'
25
25
  spec.add_runtime_dependency 'redis','~> 4.1.3'
26
26
  spec.add_runtime_dependency 'bunny','~> 2.15.0'
27
+ spec.add_runtime_dependency 'ps-ruby','~> 0.0.4'
27
28
  spec.add_runtime_dependency 'tty-markdown','~> 0.6.0'
28
29
  spec.add_runtime_dependency 'tty-pager','~> 0.12.1'
29
30
  spec.add_runtime_dependency 'colorize','~> 0.8.1'
@@ -17,7 +17,7 @@ Vagrant.configure("2") do |config|
17
17
  config.vm.provision "shell", inline: <<-SHELL
18
18
  sudo apt-get update
19
19
  sudo apt-add-repository --yes --update ppa:ansible/ansible
20
- apt-get install -y git ansible
20
+ apt-get install -y git ansible python-apt
21
21
  git clone https://github.com/Ultragreen/prometheus-splash.git
22
22
  cd prometheus-splash/templates/ansible-splash
23
23
  ansible-playbook -i inventory.dev deploy.yml
@@ -1,6 +1,7 @@
1
1
  ---
2
- - name: PREPARE TESTING ocalhost entries for test
2
+ - name: PREPARE TESTING localhost entries for test #only for testing with Vagrant, remove for real usages
3
3
  hosts: supervision_master
4
+ become: yes
4
5
  tasks:
5
6
  - lineinfile:
6
7
  path: /etc/hosts
@@ -10,7 +11,25 @@
10
11
  group: root
11
12
  mode: '0644'
12
13
  when: patch_etc_hosts
14
+ - lineinfile:
15
+ path: /etc/hosts
16
+ state: absent
17
+ regexp: '^127\.0\.1\.1'
18
+ when: patch_etc_hosts
13
19
 
20
+ - name: PREPARE packages
21
+ hosts: supervision_master #for real usage => precise all
22
+ become: yes
23
+ tasks:
24
+ - apt:
25
+ update_cache: yes
26
+ force_apt_get: yes
27
+ cache_valid_time: 3600
28
+ pkg:
29
+ - python-apt
30
+ - screen
31
+ - emacs-nox
32
+ - htop
14
33
 
15
34
 
16
35
 
@@ -18,6 +37,7 @@
18
37
  become: yes
19
38
  hosts: mq
20
39
  tasks:
40
+ - apt: update_cache=yes force_apt_get=yes cache_valid_time=3600
21
41
  - include_role:
22
42
  name: mq
23
43
  when: install_mq
@@ -26,6 +46,7 @@
26
46
  become: yes
27
47
  hosts: backend
28
48
  tasks:
49
+ - apt: update_cache=yes force_apt_get=yes cache_valid_time=3600
29
50
  - include_role:
30
51
  name: backend
31
52
  when: install_backend
@@ -33,17 +54,23 @@
33
54
  - name: Deploy Supervision Master
34
55
  become: yes
35
56
  hosts: supervision_master
57
+ tasks:
58
+ - apt: update_cache=yes force_apt_get=yes cache_valid_time=3600
36
59
  roles:
37
60
  - supervision_master
38
61
 
39
62
  - name: Deploy Supervision Gateway
40
63
  become: yes
41
64
  hosts: supervision_gateway
65
+ tasks:
66
+ - apt: update_cache=yes force_apt_get=yes cache_valid_time=3600
42
67
  roles:
43
68
  - supervision_gateway
44
69
 
45
70
  - name: Deploy Splash
46
71
  become: yes
47
72
  hosts: splash_nodes
73
+ tasks:
74
+ - apt: update_cache=yes force_apt_get=yes cache_valid_time=3600
48
75
  roles:
49
76
  - splash
@@ -7,6 +7,8 @@ patch_etc_hosts: true
7
7
  mq_port: 5672
8
8
  mq_admin_username: admin
9
9
  mq_admin_password: adminmdppwd
10
+ mq_ip: 127.0.0.1
11
+ mq_nodename: rabbit
10
12
 
11
13
  mq_splash_username: splash
12
14
  mq_splash_password: mdptest
@@ -1,5 +1,5 @@
1
1
 
2
2
  ---
3
- - name: restart rabbitmq
3
+ - name: restart Rabbitmq
4
4
  service: name=rabbitmq-server state=restarted
5
5
  become: yes
@@ -6,10 +6,23 @@
6
6
 
7
7
  - name: MQ enable rabbitmq plugins
8
8
  rabbitmq_plugin: names=rabbitmq_management,rabbitmq_tracing,rabbitmq_federation state=enabled
9
- notify: restart rabbitmq
9
+ notify: restart Rabbitmq
10
10
 
11
+ - name: MQ Configuration
12
+ template:
13
+ src: rabbitmq-env.conf.j2
14
+ dest: /etc/rabbitmq/rabbitmq-env.conf
15
+ owner: rabbitmq
16
+ group: rabbitmq
17
+ mode: 0644
18
+ notify: restart Rabbitmq
19
+
20
+ - name: MQ Force restart RabbitMQ for conf update directly
21
+ meta: flush_handlers
22
+
11
23
  - name: add Admin users
12
24
  rabbitmq_user:
25
+ node: "rabbit@{{ groups['mq'][0] }}"
13
26
  user: "{{ mq_admin_username }}"
14
27
  password: "{{ mq_admin_password }}"
15
28
  tags: administrator,"{{ mq_admin_username }}"
@@ -22,17 +35,20 @@
22
35
 
23
36
  - name: remove default guest user
24
37
  rabbitmq_user:
38
+ node: "rabbit@{{ groups['mq'][0] }}"
25
39
  user: guest
26
40
  state: absent
27
41
 
28
42
 
29
43
  - name: MQ Configure Splash vhost
30
44
  rabbitmq_vhost:
45
+ node: "rabbit@{{ groups['mq'][0] }}"
31
46
  name: "{{ mq_splash_vhost }}"
32
47
  state: present
33
48
 
34
49
  - name: MQ Add Splash service user
35
50
  rabbitmq_user:
51
+ node: "rabbit@{{ groups['mq'][0] }}"
36
52
  user: "{{ mq_splash_username }}"
37
53
  password: "{{ mq_splash_password }}"
38
54
  vhost: "{{ mq_splash_vhost}}"
@@ -0,0 +1,13 @@
1
+ # Defaults to rabbit. This can be useful if you want to run more than one node
2
+ # per machine - RABBITMQ_NODENAME should be unique per erlang-node-and-machine
3
+ # combination. See the clustering on a single machine guide for details:
4
+ # http://www.rabbitmq.com/clustering.html#single-machine
5
+ NODENAME={{ mq_nodename }}@{{ groups['mq'][0]}}
6
+
7
+ # By default RabbitMQ will bind to all interfaces, on IPv4 and IPv6 if
8
+ # available. Set this if you only want to bind to one network interface or#
9
+ # address family.
10
+ NODE_IP_ADDRESS={{ mq_ip }}
11
+
12
+ # Defaults to 5672.
13
+ NODE_PORT={{ mq_port }}
@@ -8,6 +8,7 @@
8
8
  gem:
9
9
  name: prometheus-splash
10
10
  state: present
11
+ user_install: no
11
12
 
12
13
  - name: SPLASH Check if setup done
13
14
  stat:
@@ -15,7 +15,7 @@ ExecStop=/usr/local/bin/splash daemon stop
15
15
  Restart=on-failure
16
16
 
17
17
  # Configures the time to wait before service is stopped forcefully.
18
- TimeoutStopSec=300
18
+ TimeoutStopSec=30
19
19
 
20
20
  [Install]
21
21
  WantedBy=multi-user.target
data/test.sh ADDED
@@ -0,0 +1,42 @@
1
+ rvmsudo splash config set
2
+ rvmsudo splash config san
3
+
4
+
5
+ splash conf version
6
+
7
+ splash conf version --no-colors
8
+ splash conf version --no-emoji
9
+
10
+ splash logs an
11
+ splash log mon
12
+ splash logs show /tmp/test
13
+ splash logs show /tmtp/toto
14
+ splash logs list
15
+ splash logs list --detail
16
+
17
+
18
+
19
+ splash com list --detail
20
+ splash com list
21
+ splash com treeview pwd
22
+ splash com show echo1
23
+ rvmsudo splash com exe true_test
24
+ rvmsudo splash com exe false_test
25
+ splash com lastrun true_test
26
+ splash com get
27
+
28
+ rvmsudo splash dae start
29
+ rvmsudo splash dae ping
30
+
31
+ rvmsudo splash com exe test_remote_call
32
+
33
+ rvmsudo splash com sched echo2 --in '2s'
34
+ rvmsudo splash com sched echo2 --in '2s' --hostname
35
+ rvmsudo splash com exe echo1 --hostname
36
+
37
+
38
+ splash com list --hostname
39
+ splash com get --all
40
+ splash com get --hostname
41
+ splash com tree echo1 --hostname
42
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prometheus-splash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Romain GEORGES
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-16 00:00:00.000000000 Z
11
+ date: 2020-04-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: 2.15.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: ps-ruby
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.0.4
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.0.4
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: tty-markdown
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -254,6 +268,7 @@ files:
254
268
  - lib/splash/commands.rb
255
269
  - lib/splash/config.rb
256
270
  - lib/splash/config/sanitycheck.rb
271
+ - lib/splash/config/service.rb
257
272
  - lib/splash/config/setup.rb
258
273
  - lib/splash/constants.rb
259
274
  - lib/splash/controller.rb
@@ -279,12 +294,12 @@ files:
279
294
  - templates/ansible-splash/group_vars/PROD.yml
280
295
  - templates/ansible-splash/group_vars/all.yml
281
296
  - templates/ansible-splash/inventory.dev
282
- - templates/ansible-splash/inventory.prod
283
297
  - templates/ansible-splash/roles/backend/handlers/main.yml
284
298
  - templates/ansible-splash/roles/backend/tasks/main.yml
285
299
  - templates/ansible-splash/roles/backend/templates/redis.conf.j2
286
300
  - templates/ansible-splash/roles/mq/handlers/main.yml
287
301
  - templates/ansible-splash/roles/mq/tasks/main.yml
302
+ - templates/ansible-splash/roles/mq/templates/rabbitmq-env.conf.j2
288
303
  - templates/ansible-splash/roles/splash/tasks/main.yml
289
304
  - templates/ansible-splash/roles/splash/templates/splash.yml.j2
290
305
  - templates/ansible-splash/roles/supervision_gateway/handlers/main.yml
@@ -295,6 +310,7 @@ files:
295
310
  - templates/ansible-splash/roles/supervision_master/templates/prometheus.yml.j2
296
311
  - templates/report.txt
297
312
  - templates/splashd.service
313
+ - test.sh
298
314
  - ultragreen_roodi_coding_convention.yml
299
315
  homepage: http://www.ultragreen.net
300
316
  licenses:
@@ -1,26 +0,0 @@
1
- # TEMPLATE
2
- [PROD:children]
3
- backend
4
- mq
5
- splash_nodes
6
- supervision_master
7
- supervision_gateway
8
-
9
-
10
- [backend]
11
- backend ansible_host=X.X.X.X
12
-
13
- [mq]
14
- mq ansible_host=X.X.X.X
15
-
16
-
17
- [splash_nodes]
18
- node1 ansible_host=X.X.X.X
19
- node2 ansible_host=X.X.X.X
20
-
21
-
22
- [supervision_gateway]
23
- pushgateway ansible_host=X.X.X.X
24
-
25
- [supervision_master]
26
- prometheus ansible_host=X.X.X.X