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
@@ -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
-