adminix 0.1.49 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
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,5 @@
1
+ require_relative 'entities/service'
2
+ require_relative 'entities/variable'
3
+ require_relative 'entities/log'
4
+ require_relative 'entities/sysload_stamp'
5
+ require_relative 'entities/job'
@@ -0,0 +1,54 @@
1
+ module Adminix
2
+ module Entities
3
+ class Job
4
+ attr_accessor :id, :script
5
+ attr_reader :output, :status, :success
6
+
7
+ STATUS_IN_QUEUE = 'in_queue'.freeze
8
+ STATUS_COMPLETED = 'completed'.freeze
9
+
10
+ def initialize(id:, script:)
11
+ @id = id
12
+ @script = script
13
+ @status = STATUS_IN_QUEUE
14
+ @created_at = Time.now
15
+ @success = false
16
+
17
+ filter_script
18
+ end
19
+
20
+ def perform
21
+ @output = `/bin/bash #{Adminix.config.scripts[:run_script]} #{script}`
22
+ @success = $?.success?
23
+ @status = STATUS_COMPLETED
24
+ @completed_at = Time.now
25
+ end
26
+
27
+ def in_queue?
28
+ @status == STATUS_IN_QUEUE
29
+ end
30
+
31
+ def completed?
32
+ @status == STATUS_COMPLETED
33
+ end
34
+
35
+ def filter_script
36
+ ['sudo', 'shutdown', 'kill'].each do |word|
37
+ @script = @script.gsub('word', '')
38
+ end
39
+ end
40
+
41
+ def to_api
42
+ {
43
+ id: @id,
44
+ status: @status,
45
+ script: @script,
46
+ success: @success,
47
+ output: @output,
48
+ created_at: @created_at,
49
+ completed_at: @completed_at
50
+ }
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,21 @@
1
+ module Adminix
2
+ module Entities
3
+ class Log
4
+ attr_reader :message, :tag, :created_at
5
+
6
+ def initialize(message, tag = nil)
7
+ @message = message
8
+ @tag = tag || 'default'
9
+ @created_at = Time.now
10
+ end
11
+
12
+ def to_api
13
+ {
14
+ message: message,
15
+ tag: tag,
16
+ created_at: created_at
17
+ }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,211 @@
1
+ require 'securerandom'
2
+
3
+ module Adminix
4
+ module Entities
5
+ class Service
6
+ attr_reader :id, :logs, :load_stamps, :jobs, :device_id, :performed_actions
7
+ attr_accessor :variables
8
+
9
+ def initialize(opts = {})
10
+ @id = opts[:id]
11
+ @device_id_path = "#{Helpers::Command.home}/.config/adminix/device_id"
12
+ @variables = []
13
+ @jobs = []
14
+ @logs = []
15
+ @load_stamps = []
16
+ @send_logs = false
17
+ @locked = false
18
+ @send_system_load = false
19
+ @performed_actions = {
20
+ watcher_started: true,
21
+ watcher_updated: false,
22
+ process_stopped: false,
23
+ process_started: false,
24
+ process_updated: false
25
+ }
26
+
27
+ define_device_id
28
+ end
29
+
30
+ def remove_completed_jobs
31
+ @jobs.each do |job|
32
+ @jobs -= [job] if job.completed?
33
+ end
34
+ end
35
+
36
+ def clean_sent_logs
37
+ return unless @send_logs
38
+ @send_logs = false
39
+ @logs = []
40
+ end
41
+
42
+ def clean_load_stamps
43
+ return unless @send_system_load
44
+ @send_system_load = false
45
+ @load_stamps = []
46
+ end
47
+
48
+ def add_new_jobs(list)
49
+ list.each do |data|
50
+ @jobs << Entities::Job.new(
51
+ id: data['id'],
52
+ script: data['script']
53
+ )
54
+ end
55
+ end
56
+
57
+ def add_logs(logs)
58
+ return if locked?
59
+ @logs += logs
60
+ end
61
+
62
+ def shift_logs(number)
63
+ @logs.shift(number)
64
+ end
65
+
66
+ def add_variable(new_var)
67
+ var = @variables.find { |v| v.key == new_var.key }
68
+ if var
69
+ index = @variables.index(var)
70
+ @variables[index] = new_var
71
+ else
72
+ @variables << new_var
73
+ end
74
+ end
75
+
76
+ def add_system_load(sys_load)
77
+ @load_stamps << sys_load
78
+ end
79
+
80
+ def shift_load_stamps(number)
81
+ @load_stamps.shift(number)
82
+ end
83
+
84
+ def allow_sending_logs
85
+ @send_logs = true
86
+ return if @logs.count.zero?
87
+ Adminix.logger.info("Sending #{@logs.count} new logs")
88
+ end
89
+
90
+ def allow_sending_system_load
91
+ @send_system_load = true
92
+ return if @load_stamps.count.zero?
93
+ Adminix.logger.info("Sending #{@load_stamps.count} new system load stamps")
94
+ end
95
+
96
+ def ensure_credentials_exists!
97
+ return unless id_defined?
98
+ Helpers::Output.display_error_and_exit('Credentials are not provided')
99
+ end
100
+
101
+ def define_device_id
102
+ if Helpers::Files.file_exists?(@device_id_path)
103
+ read_device_id
104
+ else
105
+ generate_device_id
106
+ end
107
+ end
108
+
109
+ def read_device_id
110
+ content = Helpers::Files.read_plain_file(@device_id_path)
111
+ .split("\n").first.to_s
112
+ if content.empty?
113
+ Helpers::Output.display_error_and_exit("Device ID can't be empty")
114
+ else
115
+ @device_id = content
116
+ end
117
+ end
118
+
119
+ def generate_device_id(id = nil)
120
+ @device_id = id || SecureRandom.uuid
121
+ Helpers::Files.write_plain_file(@device_id_path, @device_id)
122
+ end
123
+
124
+ # TODO: real total memory and disk
125
+ def sync_payload
126
+ {
127
+ device_id: @device_id,
128
+ watcher_started: @performed_actions[:watcher_started],
129
+ watcher_updated: @performed_actions[:watcher_updated],
130
+ process_stopped: @performed_actions[:process_stopped],
131
+ process_started: @performed_actions[:process_started],
132
+ process_updated: @performed_actions[:process_updated],
133
+ completed_jobs: completed_jobs_to_api,
134
+ logs: logs_to_api,
135
+ system_load: {
136
+ stamps: load_stamps_to_api,
137
+ total: {
138
+ memory: 1024,
139
+ disk: 10_240
140
+ }
141
+ }
142
+ }
143
+ end
144
+
145
+ def new_jobs
146
+ @jobs.select(&:in_queue?)
147
+ end
148
+
149
+ def completed_jobs
150
+ @jobs.select(&:completed?)
151
+ end
152
+
153
+ def completed_jobs_to_api
154
+ completed_jobs.map(&:to_api)
155
+ end
156
+
157
+ def logs_to_api
158
+ @send_logs ? @logs.map(&:to_api) : []
159
+ end
160
+
161
+ def load_stamps_to_api
162
+ @send_system_load ? @load_stamps.map(&:to_api) : []
163
+ end
164
+
165
+ def reset_performed_actions
166
+ @performed_actions.keys.map { |key| @performed_actions[key] = false }
167
+ end
168
+
169
+ def define_performed_action(key, value)
170
+ @performed_actions[key] = value
171
+ end
172
+
173
+ def bash_variables(file = nil)
174
+ output = ''
175
+
176
+ if file
177
+ content = (variables.map { |v| "#{v.key}=#{v.value}" }).join("\n")
178
+ Helpers::Files.rm(file)
179
+ Helpers::Files.write_plain_file(file, content)
180
+ output = file
181
+ else
182
+ variables.each { |v| output << "#{v.to_bash_export}\n" }
183
+ output << "# Run this command to configure your shell:\n" \
184
+ '# eval $(adminix env)'
185
+ end
186
+
187
+ output
188
+ end
189
+
190
+ def id_defined?
191
+ !(id || '').empty?
192
+ end
193
+
194
+ def new_jobs?
195
+ new_jobs.any?
196
+ end
197
+
198
+ def locked?
199
+ @locked == true
200
+ end
201
+
202
+ def lock
203
+ @locked = true
204
+ end
205
+
206
+ def unlock
207
+ @locked = false
208
+ end
209
+ end
210
+ end
211
+ end
@@ -0,0 +1,37 @@
1
+ module Adminix
2
+ module Entities
3
+ class SysloadStamp
4
+
5
+ attr_reader :memory_usage_mb, :cpu_load_percents, :disk_usage_mb,
6
+ :temperature, :created_at
7
+
8
+ def initialize
9
+ create_stamp
10
+ @created_at = Time.now
11
+ end
12
+
13
+ def create_stamp
14
+ case Adminix.os
15
+ when 'linux'
16
+ @memory_usage_mb, = Helpers::Command.debian_memory_load
17
+ @cpu_load_percents = Helpers::Command.debian_cpu_load
18
+ @disk_usage_mb, = Helpers::Command.debian_disk_usage
19
+ @temperature = Helpers::Command.debian_temperature
20
+ when 'mac'
21
+ @cpu_load_percents = Helpers::Command.darwin_cpu_load
22
+ @disk_usage_mb, = Helpers::Command.darwin_disk_usage
23
+ end
24
+ end
25
+
26
+ def to_api
27
+ {
28
+ memory: memory_usage_mb,
29
+ cpu: cpu_load_percents,
30
+ disk: disk_usage_mb,
31
+ temperature: temperature,
32
+ created_at: created_at
33
+ }
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,32 @@
1
+ module Adminix
2
+ module Entities
3
+ class Variable
4
+ attr_reader :key, :value
5
+
6
+ def self.all(service)
7
+ return [] unless Adminix.config.credentials_defined?
8
+
9
+ success, result = Helpers::NetHTTP.get("services/#{service.id}/options")
10
+ return [] unless success
11
+
12
+ variables = result.map do |o|
13
+ Variable.new(
14
+ key: o['key'],
15
+ value: o['value']
16
+ )
17
+ end
18
+
19
+ variables
20
+ end
21
+
22
+ def initialize(opts = {})
23
+ @key = opts[:key]
24
+ @value = opts[:value]
25
+ end
26
+
27
+ def to_bash_export
28
+ "export #{key}=\"#{value}\""
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,2 +1,7 @@
1
- require_relative 'helpers/file'
2
- require_relative 'helpers/http'
1
+ require_relative 'helpers/files'
2
+ require_relative 'helpers/output'
3
+ require_relative 'helpers/net_http'
4
+ require_relative 'helpers/command'
5
+ require_relative 'helpers/command'
6
+ require_relative 'helpers/log_reader'
7
+ require_relative 'helpers/systemctl'
@@ -0,0 +1,73 @@
1
+ module Adminix
2
+ module Helpers
3
+ module Command
4
+ def self.which(arg1)
5
+ output = `which #{arg1}`
6
+ output = output.split("\n")[0]
7
+ output.empty? ? nil : output
8
+ end
9
+
10
+ def self.whoami
11
+ output = `whoami`
12
+ output.split("\n")[0]
13
+ end
14
+
15
+ def self.home
16
+ ENV['HOME']
17
+ end
18
+
19
+ def self.git_clone(repo, branch = 'master')
20
+ bin = 'git'
21
+ `#{bin} clone #{repo} -b #{branch}`
22
+ end
23
+
24
+ def mkdir_p(dirname)
25
+ `mkdir -p #{dirname}`
26
+ end
27
+
28
+ def self.run_system_command(command)
29
+ `#{command}`
30
+ end
31
+
32
+ def self.debian_memory_load
33
+ output = `free -m | awk 'NR==2{printf "%s/%s", $3,$2,$3*100/$2 }'`
34
+ output.split('/')
35
+ end
36
+
37
+ def self.systemctl_enabled?
38
+ !`which systemctl`.length.zero?
39
+ end
40
+
41
+ def self.darwin_memory_load
42
+ output = `free -m | awk 'NR==2{printf "%s/%s", $3,$2,$3*100/$2 }'`
43
+ output.split('/')
44
+ end
45
+
46
+ def self.debian_cpu_load
47
+ `top -bn1 | grep load | awk '{printf "%.2f\\\n", $(NF-2)}'`.to_f
48
+ end
49
+
50
+ def self.darwin_cpu_load
51
+ `ps -A -o %cpu | awk '{s+=$1} END {print s}'`.to_f
52
+ end
53
+
54
+ def self.debian_disk_usage
55
+ output = `df -h | awk '$NF=="/"{printf "%d/%d\\\n", $3,$2,$5}'`
56
+ output.split('/')
57
+ end
58
+
59
+ def self.debian_temperature
60
+ output = `cat /sys/class/thermal/thermal_zone*/temp`
61
+ temperatures = output.split("\n").map(&:to_i)
62
+ return nil if temperatures.empty?
63
+ temperatures.reduce(:+) / temperatures.size
64
+ end
65
+
66
+ def self.darwin_disk_usage
67
+ output = `df -h | awk '$NF=="/"{printf "%d/%d", $3,$2,$5}'`
68
+ used, disk_size = output.split('/')
69
+ [used.to_f * 1024, disk_size.to_f * 1024]
70
+ end
71
+ end
72
+ end
73
+ end