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
@@ -1,13 +0,0 @@
1
- module Adminix
2
- module Helpers
3
- module File
4
- def self.mkdir_p(dirname)
5
- `mkdir -p #{dirname}`
6
- end
7
-
8
- def self.touch(file_path)
9
- `touch #{file_path}`
10
- end
11
- end
12
- end
13
- end
@@ -1,19 +0,0 @@
1
- module Adminix
2
- module Helpers
3
- module HTTP
4
- def self.get(path)
5
- config = Adminix::Config.instance
6
- uri = URI.parse("#{config.host}/v1/#{path}")
7
- request = Net::HTTP::Get.new(uri)
8
- request['Authorization'] = "Bearer #{config.secret_key}"
9
-
10
- opts = { use_ssl: uri.scheme == 'https' }
11
- response = Net::HTTP.start(uri.hostname, uri.port, opts) do |http|
12
- http.request(request)
13
- end
14
-
15
- JSON.parse(response.body)
16
- end
17
- end
18
- end
19
- end
@@ -1,23 +0,0 @@
1
- module Adminix
2
- module LogWatchHandler
3
- def file_modified
4
- #puts "#{path} modified"
5
- unless Service.instance.syncing_logs
6
- Service.instance.new_logs = true
7
- end
8
- end
9
-
10
- def file_moved
11
- #puts "#{path} moved"
12
- end
13
-
14
- def file_deleted
15
- #puts "#{path} deleted"
16
- end
17
-
18
- def unbind
19
- #puts "#{path} monitoring ceased"
20
- end
21
- end
22
- end
23
-
@@ -1,76 +0,0 @@
1
- require 'sinatra/base'
2
- require 'json'
3
- require 'securerandom'
4
- require 'base64'
5
- require 'openssl'
6
- # require 'digest'
7
-
8
- module Adminix
9
- class ServerSetup < Sinatra::Base
10
- get '/' do
11
- %{
12
- <html>
13
- <head>
14
- <title>Adminix start</title>
15
- </head>
16
- <body>
17
- <script type="text/javascript">
18
- var host = window.location.protocol + '//' + window.location.host;
19
- var newPath = "https://beta.adminix.io/setup-server/init?host=" + host;
20
- window.location.href = newPath;
21
- </script>
22
- </body>
23
- </html>
24
- }
25
- end
26
-
27
- get '/ping' do
28
- 'pong'
29
- end
30
-
31
- post '/data' do
32
- config = Adminix::Config.instance
33
- config.password = SecureRandom.hex
34
-
35
- content_type :json
36
- { password: config.password, image: config.image_sname }.to_json
37
- end
38
-
39
- post '/connect' do
40
- content_type :json
41
-
42
- data = {}
43
- config = Adminix::Config.instance
44
-
45
- begin
46
- decoded = Base64.decode64 request.body.read.encode('ascii-8bit')
47
- decipher = OpenSSL::Cipher::AES256.new :CBC
48
- decipher.decrypt
49
- decipher.key = config.password
50
- decipher.iv = config.iv
51
- decrypted_data = decipher.update(decoded) + decipher.final
52
- data = JSON.parse(decrypted_data)['server_setup']
53
- rescue
54
- { success: false }.to_json
55
- end
56
-
57
- config.password = ''
58
- config.service_id = data['service_id']
59
- config.secret_key = data['secret_key']
60
- config.export_credentials
61
-
62
- Thread.start do
63
- sleep(2)
64
- Adminix::Service.instance.restart!
65
- end
66
-
67
- { success: true }.to_json
68
- end
69
-
70
- set :bind, '0.0.0.0'
71
- set :port, Adminix::Config::DEFAULT_SETUP_SERVER_PORT
72
-
73
- run!
74
- end
75
- end
76
-
@@ -1,179 +0,0 @@
1
- require 'singleton'
2
- require 'net/http'
3
-
4
- module Adminix
5
- class Service
6
- include Singleton
7
-
8
- attr_accessor :new_logs
9
- attr_reader :id, :process_id, :watching_logs, :syncing_logs
10
-
11
- def initialize
12
- @id = config.service_id
13
- @watching_logs = []
14
- @new_logs = false
15
- @syncing_logs = false
16
- end
17
-
18
- def to_cable
19
- system.check_system_load
20
-
21
- {
22
- id: id,
23
- process_id: process_id,
24
- system: {
25
- processor_load: system.processor_load,
26
- memory_load: system.memory_load
27
- }
28
- }
29
- end
30
-
31
- def sync(ws_client, data)
32
- @process_id = data['process_id']
33
- config.commands = data['commands'] || []
34
-
35
- commands_queue = data['commands_queue'] || []
36
- commands_queue.each do |q|
37
- if q['status'] != 'processed'
38
- res = execute_command(q['command_key'], q['process_id'], q['args'] || {})
39
- ws_client.perform(:task_completed, res) if ws_client.subscribed?
40
- end
41
- end
42
- end
43
-
44
- def sync_logs(ws_client)
45
- return unless new_logs
46
-
47
- @syncing_logs = true
48
-
49
- @watching_logs.each do |l|
50
- initial_length = l[:lines]
51
- current_length = file_lines_number(l[:path])
52
- new_lines = current_length > initial_length ? current_length - initial_length : 100
53
- lines = `tail -#{new_lines} #{l[:path]}`.split("\n") rescue []
54
- payload = lines.map { |line| { created_at: Time.now.to_s, level: 'NOTICE', message: line } }
55
- begin
56
- puts "Syncing new logs"
57
- ws_client.perform(:add_logs, { logs: payload }) if ws_client.subscribed?
58
- rescue
59
- end
60
- end
61
-
62
- count_logs_lines
63
-
64
- @new_logs = false
65
- @syncing_logs = false
66
- end
67
-
68
- def options_to_envs
69
- data = fetch_options
70
-
71
- data['result'].each do |o|
72
- puts "export #{o['key'].upcase}=\"#{o['value']}\""
73
- end
74
-
75
- puts "# Run this command to configure your shell:\n" +
76
- "# eval $(adminix env)"
77
- end
78
-
79
- def options_to_envs_inline
80
- data = fetch_options
81
- str = 'export'
82
-
83
- data['result'].each do |o|
84
- str << " #{o['key'].upcase}=\"#{o['value']}\""
85
- end
86
-
87
- str
88
- end
89
-
90
- def fetch_options
91
- Helpers::HTTP.get("services/#{id}/options")
92
- end
93
-
94
- def count_logs_lines
95
- @watching_logs = config.watch_log_files.map do |file_path|
96
- { lines: file_lines_number(file_path), path: file_path }
97
- end
98
- end
99
-
100
- def restart!
101
- stop!
102
- end
103
-
104
- def stop!
105
- system.log 'Stopping process'
106
- case config.mode
107
- when 'classic'
108
- system.eval("#{config.scripts[:process_stop]} && #{config.scripts[:process_start]}")
109
- when 'docker'
110
- Process.kill('INT', 1) rescue nil
111
- end
112
- end
113
-
114
- def download_source
115
- data = fetch_options
116
- unless data['success']
117
- puts 'Error, please try again later!'
118
- return
119
- end
120
-
121
- vars = data['result'] || []
122
- bin = 'git'
123
- repo_var = vars.find { |v| v['key'] == 'git_repo' }
124
- branch_var = vars.find { |v| v['key'] == 'git_branch' }
125
-
126
- if repo_var && repo_var['value'] && branch_var
127
- repo = repo_var['value']
128
- branch = branch_var['value'] || 'master'
129
- `#{bin} clone #{repo} -b #{branch}`
130
- else
131
- puts 'Please define your GIT repository and branch'
132
- end
133
- end
134
-
135
- private
136
-
137
- def config
138
- Config.instance
139
- end
140
-
141
- def system
142
- System.instance
143
- end
144
-
145
- def file_lines_number(file_path)
146
- File.exists?(file_path) ? `wc -l #{file_path}`.to_i : 0
147
- end
148
-
149
- def execute_command(key, process_id, args)
150
- command = config.commands.find { |c| c['key'] == key }
151
- script = command['command'].dup
152
-
153
- # TODO frontend fix attribute args
154
- args.each { |hs| script.gsub!("%{#{hs[0]}}", hs[1]) }
155
-
156
- # export_envs = options_to_envs_inline
157
- # script = "cd #{config.working_dir} && #{export_envs} && #{script}"
158
-
159
- system.log 'Executing command: '
160
- system.log '-----------------------------------'
161
- system.log script
162
- system.log '-----------------------------------'
163
-
164
- output = system.eval("#{config.scripts[:run_script]} #{script}")
165
-
166
- system.log 'Command execution output: '
167
- system.log '-----------------------------------'
168
- system.log output
169
- system.log '-----------------------------------'
170
-
171
- {
172
- id: process_id,
173
- success: true,
174
- output: output
175
- }
176
- end
177
- end
178
- end
179
-
@@ -1,3 +0,0 @@
1
- # require_relative 'setup/views'
2
- # require_relative 'setup/services'
3
- # require_relative 'setup/routes'
@@ -1,113 +0,0 @@
1
- require 'sinatra/base'
2
-
3
- module Adminix::Setup
4
- class Routes < Sinatra::Base
5
- get '/' do
6
- render('root')
7
- end
8
-
9
- get '/login' do
10
- render('login')
11
- end
12
-
13
- post '/login' do
14
- result = Services.create_session(params[:session])
15
- case result[0]
16
- when :ok
17
- redirect "/create-service?t=#{result[1]}"
18
- when :error
19
- errors = result[1]
20
- render('login', session: params[:session], errors: errors)
21
- end
22
- end
23
-
24
- get '/sign-up' do
25
- render('sign_up')
26
- end
27
-
28
- post '/sign-up' do
29
- result = Services.create_user(params[:user])
30
- case result[0]
31
- when :ok
32
- redirect "/create-service?t=#{result[1]}"
33
- when :error
34
- errors = result[1]
35
- render('sign_up', user: params[:user], errors: errors)
36
- end
37
- end
38
-
39
- get '/create-service' do
40
- if params[:t]
41
- case (result = Services.get_existing_services(params[:t]))[0]
42
- when :ok
43
- render('create_service', token: params[:t], service_exists: result[1] != 0)
44
- when :error
45
- render('error')
46
- end
47
- else
48
- redirect '/sign-up'
49
- end
50
- end
51
-
52
- post '/create-service' do
53
- if params[:t]
54
- case (result = Services.create_service(params[:t], params[:service]))[0]
55
- when :ok
56
- redirect "/complete?t=#{params[:t]}&id=#{result[1]['id']}"
57
- when :error
58
- render('error')
59
- end
60
- else
61
- redirect '/sign-up'
62
- end
63
- end
64
-
65
- get '/connect-service' do
66
- if params[:t]
67
- case (result = Services.get_existing_services(params[:t]))[0]
68
- when :ok
69
- render('connect_service', token: params[:t], services: result[1])
70
- when :error
71
- render('error')
72
- end
73
- else
74
- redirect '/sign-up'
75
- end
76
- end
77
-
78
- post '/connect-service' do
79
- redirect "/complete?t=#{params[:t]}&id=#{params[:service][:id]}"
80
- end
81
-
82
- get '/complete' do
83
- if params[:t] && params[:id]
84
- id_is_valid = Services.verify_service_id(params[:t], params[:id])
85
- secret_key = Services.get_secret_key(params[:t])
86
- if id_is_valid && !secret_key.nil?
87
- Services.import_settings(secret_key, params[:id])
88
- Thread.start do
89
- sleep(2)
90
- Adminix::Service.instance.restart!
91
- end
92
- render('complete')
93
- else
94
- render('error')
95
- end
96
- else
97
- render('error')
98
- end
99
- end
100
-
101
- private
102
-
103
- def render(view_name, assigns={})
104
- Views.send("#{view_name}_view", assigns)
105
- end
106
-
107
- set :bind, '0.0.0.0'
108
- set :port, Adminix::Config::DEFAULT_SETUP_SERVER_PORT
109
-
110
- run!
111
- end
112
- end
113
-
@@ -1,139 +0,0 @@
1
- require 'net/http'
2
- require 'json'
3
-
4
- module Adminix::Setup
5
- module Services
6
- def self.create_session(payload)
7
- uri = URI.parse("#{config.host}/v1/profile/session")
8
- request = Net::HTTP::Post.new(uri)
9
- request['Content-Type'] = 'application/json'
10
- request.body = {
11
- session: {
12
- connect_type: 'email',
13
- connect_data: {
14
- email: payload[:email],
15
- password: payload[:password]
16
- }
17
- }
18
- }.to_json
19
- opts = { use_ssl: uri.scheme == 'https' }
20
-
21
- response = Net::HTTP.start(uri.hostname, uri.port, opts) do |http|
22
- http.request(request)
23
- end
24
-
25
- data = JSON.parse(response.body)
26
-
27
- data['success'] == true ? [:ok, data['result']['token']] : [:error, { email: ['Invalid credentials'] }]
28
- end
29
-
30
- def self.create_user(payload)
31
- uri = URI.parse("#{config.host}/v1/profile")
32
- request = Net::HTTP::Post.new(uri)
33
- request['Content-Type'] = 'application/json'
34
- request.body = {
35
- profile: {
36
- connect_type: 'email',
37
- connect_data: {
38
- email: payload[:email],
39
- first_name: payload[:first_name],
40
- last_name: payload[:last_name],
41
- password: payload[:password],
42
- locale: 'en'
43
- }
44
- }
45
- }.to_json
46
- opts = { use_ssl: uri.scheme == 'https' }
47
-
48
- response = Net::HTTP.start(uri.hostname, uri.port, opts) do |http|
49
- http.request(request)
50
- end
51
-
52
- data = JSON.parse(response.body)
53
-
54
- data['success'] == true ? [:ok, data['result']['token']] : [:error, data['result']]
55
- end
56
-
57
- def self.create_service(access_token, payload)
58
- uri = URI.parse("#{config.host}/v1/services")
59
- request = Net::HTTP::Post.new(uri)
60
- request['Content-Type'] = 'application/json'
61
- request['X-Auth-Token'] = access_token
62
- request.body = {
63
- service: {
64
- name: payload[:name]
65
- }
66
- }.to_json
67
- opts = { use_ssl: uri.scheme == 'https' }
68
-
69
- response = Net::HTTP.start(uri.hostname, uri.port, opts) do |http|
70
- http.request(request)
71
- end
72
-
73
- data = JSON.parse(response.body)
74
-
75
- data['success'] == true ? [:ok, data['result']] : [:error, data['result']]
76
- end
77
-
78
- def self.get_existing_services(access_token)
79
- uri = URI.parse("#{config.host}/v1/services")
80
- request = Net::HTTP::Get.new(uri)
81
- request["X-Auth-Token"] = access_token
82
- opts = { use_ssl: uri.scheme == 'https' }
83
-
84
- response = Net::HTTP.start(uri.hostname, uri.port, opts) do |http|
85
- http.request(request)
86
- end
87
-
88
- data = JSON.parse(response.body) rescue {}
89
-
90
- data['success'] == true ? [:ok, data['result']] : [:error, []]
91
- end
92
-
93
- def self.get_secret_key(access_token)
94
- uri = URI.parse("#{config.host}/v1/profile/session")
95
- request = Net::HTTP::Get.new(uri)
96
- request["X-Auth-Token"] = access_token
97
- opts = { use_ssl: uri.scheme == 'https' }
98
-
99
- response = Net::HTTP.start(uri.hostname, uri.port, opts) do |http|
100
- http.request(request)
101
- end
102
-
103
- data = JSON.parse(response.body) rescue {}
104
-
105
- data['result']['user']['secret_key'] rescue nil
106
- end
107
-
108
- def self.verify_service_id(access_token, service_id)
109
- uri = URI.parse("#{config.host}/v1/services/#{service_id}")
110
- request = Net::HTTP::Get.new(uri)
111
- request["X-Auth-Token"] = access_token
112
- opts = { use_ssl: uri.scheme == 'https' }
113
-
114
- response = Net::HTTP.start(uri.hostname, uri.port, opts) do |http|
115
- http.request(request)
116
- end
117
-
118
- data = JSON.parse(response.body) rescue {}
119
-
120
- data['success'] == true
121
- end
122
-
123
- private
124
-
125
- def self.config
126
- Adminix::Config.instance
127
- end
128
-
129
- def self.import_settings(secret_key, service_id)
130
- config = Adminix::Config.instance
131
- config.service_id = service_id
132
- config.secret_key = secret_key
133
- config.export_credentials
134
-
135
- true
136
- end
137
- end
138
- end
139
-