prometheus-splash 0.4.5 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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