adminix 0.1.49 → 0.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.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -0
  3. data/adminix.gemspec +1 -4
  4. data/app/assets/images/logo.png +0 -0
  5. data/app/assets/javascripts/application.js +50 -0
  6. data/app/assets/javascripts/bootstrap.min.js +7 -0
  7. data/app/assets/javascripts/dataTables.bootstrap4.js +184 -0
  8. data/app/assets/javascripts/jquery.dataTables.js +15243 -0
  9. data/app/assets/javascripts/jquery.min.js +2 -0
  10. data/app/assets/javascripts/sb-admin-2.min.js +6 -0
  11. data/app/assets/stylesheets/bootstrap.min.css +6 -0
  12. data/app/assets/stylesheets/dataTables.bootstrap.css +314 -0
  13. data/app/assets/stylesheets/dataTables.responsive.css +106 -0
  14. data/app/assets/stylesheets/font-awesome.min.css +4 -0
  15. data/app/assets/stylesheets/sb-admin-2.min.css +5 -0
  16. data/app/views/scripts/restart_watcher.sh.erb +9 -0
  17. data/app/views/scripts/run_script.sh.erb +12 -0
  18. data/app/views/scripts/start_process.sh.erb +7 -0
  19. data/app/views/scripts/stop_process.sh.erb +7 -0
  20. data/app/views/scripts/update_process.sh.erb +24 -0
  21. data/app/views/scripts/update_watcher.sh.erb +3 -0
  22. data/app/views/web/dashboard.html.erb +90 -0
  23. data/app/views/web/job.html.erb +46 -0
  24. data/app/views/web/link.html.erb +12 -0
  25. data/app/views/web/loadstamp.html.erb +57 -0
  26. data/app/views/web/log.html.erb +49 -0
  27. data/app/views/web/partials/footer.html.erb +11 -0
  28. data/app/views/web/partials/header.html.erb +50 -0
  29. data/bin/install_adminix +40 -0
  30. data/bin/push +13 -0
  31. data/development.log +0 -0
  32. data/exe/adminix +91 -28
  33. data/lib/adminix.rb +42 -5
  34. data/lib/adminix/config.rb +170 -96
  35. data/lib/adminix/entities.rb +5 -0
  36. data/lib/adminix/entities/job.rb +54 -0
  37. data/lib/adminix/entities/log.rb +21 -0
  38. data/lib/adminix/entities/service.rb +211 -0
  39. data/lib/adminix/entities/sysload_stamp.rb +37 -0
  40. data/lib/adminix/entities/variable.rb +32 -0
  41. data/lib/adminix/helpers.rb +7 -2
  42. data/lib/adminix/helpers/command.rb +73 -0
  43. data/lib/adminix/helpers/files.rb +82 -0
  44. data/lib/adminix/helpers/log_reader.rb +16 -0
  45. data/lib/adminix/helpers/net_http.rb +63 -0
  46. data/lib/adminix/helpers/output.rb +28 -0
  47. data/lib/adminix/helpers/systemctl.rb +54 -0
  48. data/lib/adminix/services.rb +3 -0
  49. data/lib/adminix/services/app_service.rb +143 -0
  50. data/lib/adminix/services/logs_service.rb +13 -0
  51. data/lib/adminix/services/system_load_service.rb +16 -0
  52. data/lib/adminix/version.rb +1 -1
  53. data/lib/adminix/watcher.rb +76 -144
  54. data/lib/adminix/web.rb +4 -0
  55. data/lib/adminix/web/router.rb +98 -0
  56. data/lib/adminix/web/server.rb +60 -0
  57. data/lib/adminix/web/view_helper.rb +14 -0
  58. data/lib/event_machine.rb +2 -0
  59. data/lib/event_machine/http_server.rb +2 -0
  60. data/lib/event_machine/http_server/response.rb +314 -0
  61. data/lib/event_machine/http_server/server.rb +107 -0
  62. data/lib/event_machine/tail.rb +2 -0
  63. data/lib/event_machine/tail/filetail.rb +470 -0
  64. data/lib/event_machine/tail/globwatcher.rb +294 -0
  65. metadata +60 -45
  66. data/lib/adminix/errors.rb +0 -7
  67. data/lib/adminix/helpers/file.rb +0 -13
  68. data/lib/adminix/helpers/http.rb +0 -19
  69. data/lib/adminix/log_watch_handler.rb +0 -23
  70. data/lib/adminix/server_setup.rb +0 -76
  71. data/lib/adminix/service.rb +0 -179
  72. data/lib/adminix/setup.rb +0 -3
  73. data/lib/adminix/setup/routes.rb +0 -113
  74. data/lib/adminix/setup/services.rb +0 -139
  75. data/lib/adminix/setup/views.rb +0 -183
  76. data/lib/adminix/system.rb +0 -106
  77. data/views/daemon_scripts/upstart.conf.erb +0 -23
@@ -0,0 +1,294 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "filetail"
4
+ require "eventmachine"
5
+ require "logger"
6
+ require "set"
7
+
8
+ EventMachine.epoll if EventMachine.epoll?
9
+ EventMachine.kqueue = true if EventMachine.kqueue?
10
+
11
+ # A file glob pattern watcher for EventMachine.
12
+ #
13
+ # If you are unfamiliar with globs, see Wikipedia:
14
+ # http://en.wikipedia.org/wiki/Glob_(programming)
15
+ #
16
+ # Any glob supported by Dir#glob will work with
17
+ # this class.
18
+ #
19
+ # This class will allow you to get notified whenever a file
20
+ # is created or deleted that matches your glob.
21
+ #
22
+ # If you are subclassing, here are the methods you should implement:
23
+ # file_found(path)
24
+ # file_deleted(path)
25
+ #
26
+ # See alsoe
27
+ # * EventMachine::watch_glob
28
+ # * EventMachine::FileGlobWatch#file_found
29
+ # * EventMachine::FileGlobWatch#file_deleted
30
+ #
31
+ class EventMachine::FileGlobWatch
32
+ # Watch a glob
33
+ #
34
+ # * glob - a string path or glob, such as "/var/log/*.log"
35
+ # * interval - number of seconds between scanning the glob for changes
36
+ def initialize(glob, interval=60)
37
+ @glob = glob
38
+ @files = Hash.new
39
+ @watches = Hash.new
40
+ @logger = Logger.new(STDOUT)
41
+ @logger.level = ($DEBUG and Logger::DEBUG or Logger::WARN)
42
+ @interval = interval
43
+ start
44
+ end # def initialize
45
+
46
+ # This method may be called to stop watching
47
+ # TODO(sissel): make 'stop' stop all active watches, too?
48
+ public
49
+ def stop
50
+ @find_files_interval.cancel if @find_files_interval
51
+ end
52
+
53
+ # This method may be called to start watching
54
+ #
55
+ public
56
+ def start
57
+ # We periodically check here because it is easier than writing our own glob
58
+ # parser (so we can smartly watch globs like /foo/*/bar*/*.log)
59
+ #
60
+ # Reasons to fix this -
61
+ # This will likely perform badly on globs that result in a large number of
62
+ # files.
63
+ EM.next_tick do
64
+ find_files
65
+ @find_files_interval = EM.add_periodic_timer(@interval) do
66
+ find_files
67
+ end
68
+ end # EM.next_tick
69
+ end
70
+
71
+ # This method is called when a new file is found
72
+ #
73
+ # * path - the string path of the file found
74
+ #
75
+ # You must implement this in your subclass or module for it
76
+ # to work with EventMachine::watch_glob
77
+ public
78
+ def file_found(path)
79
+ raise NotImplementedError.new("#{self.class.name}#file_found is not "\
80
+ "implemented. Did you forget to implement this in your subclass or "\
81
+ "module?")
82
+ end # def file_found
83
+
84
+ # This method is called when a file is deleted.
85
+ #
86
+ # * path - the string path of the file deleted
87
+ #
88
+ # You must implement this in your subclass or module for it
89
+ # to work with EventMachine::watch_glob
90
+ public
91
+ def file_deleted(path)
92
+ raise NotImplementedError.new("#{self.class.name}#file_deleted is not "\
93
+ "implemented. Did you forget to implement this in your subclass or "\
94
+ "module?")
95
+ end # def file_found
96
+
97
+ private
98
+ def find_files
99
+ @logger.info("Searching for files in #{@glob}")
100
+ list = Dir.glob(@glob)
101
+
102
+ known_files = @files.clone
103
+ list.each do |path|
104
+ fileinfo = FileInfo.new(path) rescue next
105
+ # Skip files that have the same inode (renamed or hardlinked)
106
+ known_files.delete(fileinfo.stat.ino)
107
+ next if @files.include?(fileinfo.stat.ino)
108
+
109
+ track(fileinfo)
110
+ file_found(path)
111
+ end
112
+
113
+ # Report missing files.
114
+ known_files.each do |inode, fileinfo|
115
+ remove(fileinfo)
116
+ end
117
+ end # def find_files
118
+
119
+ # Remove a file from being watched and notify file_deleted()
120
+ private
121
+ def remove(fileinfo)
122
+ @files.delete(fileinfo.stat.ino)
123
+ @watches.delete(fileinfo.path)
124
+ file_deleted(fileinfo.path)
125
+ end # def remove
126
+
127
+ # Add a file to watch and notify file_found()
128
+ private
129
+ def track(fileinfo)
130
+ @files[fileinfo.stat.ino] = fileinfo
131
+
132
+ # If EventMachine::watch_file fails, that's ok, I guess.
133
+ # We'll still find the file 'missing' from the next glob attempt.
134
+ #begin
135
+ # EM currently has a bug that only the first handler for a watch_file
136
+ # on each file gets events. This causes globtails to never get data
137
+ # since the glob is watching the file already.
138
+ # Until we fix that, let's skip file watching here.
139
+ #@watches[path] = EventMachine::watch_file(path, FileWatcher, self) do |path|
140
+ # remove(path)
141
+ #end
142
+ #rescue Errno::EACCES => e
143
+ #@logger.warn(e)
144
+ #end
145
+ end # def watch
146
+
147
+ private
148
+ class FileWatcher < EventMachine::FileWatch
149
+ def initialize(globwatch, &block)
150
+ @globwatch = globwatch
151
+ @block = block
152
+ end
153
+
154
+ def file_moved
155
+ stop_watching
156
+ block.call path
157
+ end
158
+
159
+ def file_deleted
160
+ block.call path
161
+ end
162
+ end # class EventMachine::FileGlobWatch::FileWatcher < EventMachine::FileWatch
163
+
164
+ private
165
+ class FileInfo
166
+ attr_reader :path
167
+ attr_reader :stat
168
+
169
+ def initialize(path)
170
+ @path = path
171
+ @stat = File.stat(path)
172
+ end
173
+ end # class FileInfo
174
+ end # class EventMachine::FileGlobWatch
175
+
176
+ # A glob tailer for EventMachine
177
+ #
178
+ # This class combines features of EventMachine::file_tail and
179
+ # EventMachine::watch_glob.
180
+ #
181
+ # You won't generally subclass this class (See EventMachine::FileGlobWatch)
182
+ #
183
+ # See also: EventMachine::glob_tail
184
+ #
185
+ class EventMachine::FileGlobWatchTail < EventMachine::FileGlobWatch
186
+ # Initialize a new file glob tail.
187
+ #
188
+ # * path - glob or file path (string)
189
+ # * handler - a module or subclass of EventMachine::FileTail
190
+ # See also EventMachine::file_tail
191
+ # * interval - how often (seconds) the glob path should be scanned
192
+ # * exclude - an array of Regexp (or anything with .match) for
193
+ # excluding from things to tail
194
+ #
195
+ # The remainder of arguments are passed to EventMachine::file_tail as
196
+ # EventMachine::file_tail(path_found, handler, *args, &block)
197
+ public
198
+ def initialize(path, handler=nil, interval=60, exclude=[], *args, &block)
199
+ super(path, interval)
200
+ @handler = handler
201
+ @args = args
202
+ @exclude = exclude
203
+
204
+ if block_given?
205
+ @handler = block
206
+ end
207
+ end # def initialize
208
+
209
+ public
210
+ def file_found(path)
211
+ begin
212
+ @logger.info "#{self.class}: Trying #{path}"
213
+ @exclude.each do |exclude|
214
+ @logger.info "#{self.class}: Testing #{exclude} =~ #{path} == #{exclude.match(path) != nil}"
215
+ if exclude.match(path) != nil
216
+ file_excluded(path)
217
+ return
218
+ end
219
+ end
220
+ @logger.info "#{self.class}: Watching #{path}"
221
+
222
+ if @handler.is_a? Proc
223
+ EventMachine::file_tail(path, nil, *@args, &@handler)
224
+ else
225
+ EventMachine::file_tail(path, @handler, *@args)
226
+ end
227
+ rescue Errno::EACCES => e
228
+ file_error(path, e)
229
+ rescue Errno::EISDIR => e
230
+ file_error(path, e)
231
+ end
232
+ end # def file_found
233
+
234
+ public
235
+ def file_excluded(path)
236
+ @logger.info "#{self.class}: Skipping path #{path} due to exclude rule"
237
+ end # def file_excluded
238
+
239
+ public
240
+ def file_deleted(path)
241
+ # Nothing to do
242
+ end # def file_deleted
243
+
244
+ public
245
+ def file_error(path, e)
246
+ $stderr.puts "#{e.class} while trying to tail #{path}"
247
+ # otherwise, drop the error by default
248
+ end # def file_error
249
+ end # class EventMachine::FileGlobWatchHandler
250
+
251
+ module EventMachine
252
+ # Watch a glob and tail any files found.
253
+ #
254
+ # * glob - a string path or glob, such as /var/log/*.log
255
+ # * handler - a module or subclass of EventMachine::FileGlobWatchTail.
256
+ # handler can be omitted if you give a block.
257
+ #
258
+ # If you give a block and omit the handler parameter, then the behavior
259
+ # is that your block is called for every line read from any file the same
260
+ # way EventMachine::file_tail does when called with a block.
261
+ #
262
+ # See EventMachine::FileGlobWatchTail for the callback methods.
263
+ # See EventMachine::file_tail for more information about block behavior.
264
+ def self.glob_tail(glob, handler=nil, *args, &block)
265
+ handler = EventMachine::FileGlobWatchTail if handler == nil
266
+ args.unshift(glob)
267
+ klass = klass_from_handler(EventMachine::FileGlobWatchTail, handler, *args)
268
+ c = klass.new(*args, &block)
269
+ return c
270
+ end
271
+
272
+ # Watch a glob for any files.
273
+ #
274
+ # * glob - a string path or glob, such as "/var/log/*.log"
275
+ # * handler - must be a module or a subclass of EventMachine::FileGlobWatch
276
+ #
277
+ # The remaining (optional) arguments are passed to your handler like this:
278
+ # If you call this:
279
+ # EventMachine.watch_glob("/var/log/*.log", YourHandler, 1, 2, 3, ...)
280
+ # This will be invoked when new matching files are found:
281
+ # YourHandler.new(path_found, 1, 2, 3, ...)
282
+ # ^ path_found is the new path found by the glob
283
+ #
284
+ # See EventMachine::FileGlobWatch for the callback methods.
285
+ def self.watch_glob(glob, handler=nil, *args)
286
+ # This code mostly styled on what EventMachine does in many of it's other
287
+ # methods.
288
+ args = [glob, *args]
289
+ klass = klass_from_handler(EventMachine::FileGlobWatch, handler, *args);
290
+ c = klass.new(*args)
291
+ yield c if block_given?
292
+ return c
293
+ end # def EventMachine::watch_glob
294
+ end # module EventMachine
metadata CHANGED
@@ -1,43 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adminix
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.49
4
+ version: '0.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Dyl
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-05-16 00:00:00.000000000 Z
11
+ date: 2018-10-15 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: eventmachine
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - '='
18
- - !ruby/object:Gem::Version
19
- version: 1.2.5
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - '='
25
- - !ruby/object:Gem::Version
26
- version: 1.2.5
27
- - !ruby/object:Gem::Dependency
28
- name: action_cable_client
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '='
32
- - !ruby/object:Gem::Version
33
- version: 2.0.2
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - '='
39
- - !ruby/object:Gem::Version
40
- version: 2.0.2
41
13
  - !ruby/object:Gem::Dependency
42
14
  name: json
43
15
  requirement: !ruby/object:Gem::Requirement
@@ -67,19 +39,19 @@ dependencies:
67
39
  - !ruby/object:Gem::Version
68
40
  version: 2.1.0
69
41
  - !ruby/object:Gem::Dependency
70
- name: sinatra
42
+ name: eventmachine
71
43
  requirement: !ruby/object:Gem::Requirement
72
44
  requirements:
73
45
  - - '='
74
46
  - !ruby/object:Gem::Version
75
- version: 2.0.0
47
+ version: 1.2.7
76
48
  type: :runtime
77
49
  prerelease: false
78
50
  version_requirements: !ruby/object:Gem::Requirement
79
51
  requirements:
80
52
  - - '='
81
53
  - !ruby/object:Gem::Version
82
- version: 2.0.0
54
+ version: 1.2.7
83
55
  - !ruby/object:Gem::Dependency
84
56
  name: bundler
85
57
  requirement: !ruby/object:Gem::Requirement
@@ -179,27 +151,70 @@ files:
179
151
  - README.md
180
152
  - Rakefile
181
153
  - adminix.gemspec
154
+ - app/assets/images/logo.png
155
+ - app/assets/javascripts/application.js
156
+ - app/assets/javascripts/bootstrap.min.js
157
+ - app/assets/javascripts/dataTables.bootstrap4.js
158
+ - app/assets/javascripts/jquery.dataTables.js
159
+ - app/assets/javascripts/jquery.min.js
160
+ - app/assets/javascripts/sb-admin-2.min.js
161
+ - app/assets/stylesheets/bootstrap.min.css
162
+ - app/assets/stylesheets/dataTables.bootstrap.css
163
+ - app/assets/stylesheets/dataTables.responsive.css
164
+ - app/assets/stylesheets/font-awesome.min.css
165
+ - app/assets/stylesheets/sb-admin-2.min.css
166
+ - app/views/scripts/restart_watcher.sh.erb
167
+ - app/views/scripts/run_script.sh.erb
168
+ - app/views/scripts/start_process.sh.erb
169
+ - app/views/scripts/stop_process.sh.erb
170
+ - app/views/scripts/update_process.sh.erb
171
+ - app/views/scripts/update_watcher.sh.erb
172
+ - app/views/web/dashboard.html.erb
173
+ - app/views/web/job.html.erb
174
+ - app/views/web/link.html.erb
175
+ - app/views/web/loadstamp.html.erb
176
+ - app/views/web/log.html.erb
177
+ - app/views/web/partials/footer.html.erb
178
+ - app/views/web/partials/header.html.erb
182
179
  - bin/build
183
180
  - bin/console
181
+ - bin/install_adminix
182
+ - bin/push
184
183
  - bin/setup
184
+ - development.log
185
185
  - exe/adminix
186
186
  - lib/adminix.rb
187
187
  - lib/adminix/config.rb
188
- - lib/adminix/errors.rb
188
+ - lib/adminix/entities.rb
189
+ - lib/adminix/entities/job.rb
190
+ - lib/adminix/entities/log.rb
191
+ - lib/adminix/entities/service.rb
192
+ - lib/adminix/entities/sysload_stamp.rb
193
+ - lib/adminix/entities/variable.rb
189
194
  - lib/adminix/helpers.rb
190
- - lib/adminix/helpers/file.rb
191
- - lib/adminix/helpers/http.rb
192
- - lib/adminix/log_watch_handler.rb
193
- - lib/adminix/server_setup.rb
194
- - lib/adminix/service.rb
195
- - lib/adminix/setup.rb
196
- - lib/adminix/setup/routes.rb
197
- - lib/adminix/setup/services.rb
198
- - lib/adminix/setup/views.rb
199
- - lib/adminix/system.rb
195
+ - lib/adminix/helpers/command.rb
196
+ - lib/adminix/helpers/files.rb
197
+ - lib/adminix/helpers/log_reader.rb
198
+ - lib/adminix/helpers/net_http.rb
199
+ - lib/adminix/helpers/output.rb
200
+ - lib/adminix/helpers/systemctl.rb
201
+ - lib/adminix/services.rb
202
+ - lib/adminix/services/app_service.rb
203
+ - lib/adminix/services/logs_service.rb
204
+ - lib/adminix/services/system_load_service.rb
200
205
  - lib/adminix/version.rb
201
206
  - lib/adminix/watcher.rb
202
- - views/daemon_scripts/upstart.conf.erb
207
+ - lib/adminix/web.rb
208
+ - lib/adminix/web/router.rb
209
+ - lib/adminix/web/server.rb
210
+ - lib/adminix/web/view_helper.rb
211
+ - lib/event_machine.rb
212
+ - lib/event_machine/http_server.rb
213
+ - lib/event_machine/http_server/response.rb
214
+ - lib/event_machine/http_server/server.rb
215
+ - lib/event_machine/tail.rb
216
+ - lib/event_machine/tail/filetail.rb
217
+ - lib/event_machine/tail/globwatcher.rb
203
218
  homepage: https://adminix.io
204
219
  licenses:
205
220
  - MIT
@@ -1,7 +0,0 @@
1
- require 'airbrake-ruby'
2
-
3
- Airbrake.configure do |c|
4
- c.host = 'http://ec2-18-217-189-42.us-east-2.compute.amazonaws.com'
5
- c.project_id = 1 # required, but any positive integer works
6
- c.project_key = 'efb1c025d1abb9c4ccb828ebaf9ea68f'
7
- end