adminix 0.1.24 → 0.1.25
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/exe/adminix +1 -3
- data/lib/adminix/config.rb +69 -12
- data/lib/adminix/log_watch_handler.rb +23 -0
- data/lib/adminix/service.rb +47 -4
- data/lib/adminix/setup/routes.rb +5 -1
- data/lib/adminix/setup/services.rb +5 -4
- data/lib/adminix/version.rb +1 -1
- data/lib/adminix/watcher.rb +40 -8
- data/lib/adminix.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed51b6024e1e9da59e6f64d6ec5dc5187d59bd46
|
4
|
+
data.tar.gz: d595961de804152a6d571b761e749a0a6ef65f14
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca709fe8f560c59566a2046c59d2c0c06c35efe9192b9d94b81a51c4b09d31386688ed56b331716cef6ac4dfdf81f74c9025d7c81dd5191e4ee52711cabbdb92
|
7
|
+
data.tar.gz: fce3a9bed9d92d62e6b70e0b8f4b36e417c0a545ab7189585e58fd4d7a6d49637273c2fd71ce5fb97be5535709e3c7178fd3a2c73b069f72b2927ae3c96289bf
|
data/exe/adminix
CHANGED
@@ -48,9 +48,7 @@ unless options[:action] == "help"
|
|
48
48
|
config.secret_key = options[:secret_key]
|
49
49
|
config.service_id = options[:service_id]
|
50
50
|
config.daemon = options[:daemonize]
|
51
|
-
|
52
|
-
config.read_creds_file
|
53
|
-
end
|
51
|
+
config.read_local_config
|
54
52
|
end
|
55
53
|
|
56
54
|
case options[:action]
|
data/lib/adminix/config.rb
CHANGED
@@ -6,35 +6,92 @@ module Adminix
|
|
6
6
|
include Singleton
|
7
7
|
|
8
8
|
DEFAULT_HOST = 'https://api.adminix.io'.freeze
|
9
|
+
DEFAULT_WEBSOCKET_HOST = 'wss://api.adminix.io/websocket'.freeze
|
9
10
|
DEFAULT_SETUP_SERVER_PORT = '8080'
|
10
11
|
|
11
|
-
attr_accessor :service_id, :secret_key, :host, :commands, :daemon, :setup_server_port
|
12
|
+
attr_accessor :service_id, :secret_key, :host, :commands, :daemon, :setup_server_port, :scripts, :watch_log_files, :watcher_sync_period, :logs_sync_period, :websocket_path, :mode
|
12
13
|
|
13
14
|
def initialize
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
@host = ENV['ADMINIX_HOST'] || DEFAULT_HOST
|
16
|
+
@setup_server_port = ENV['ADMINIX_SETUP_SERVER_PORT'] || DEFAULT_SETUP_SERVER_PORT
|
17
|
+
@commands = []
|
18
|
+
@watcher_sync_period = 10
|
19
|
+
@logs_sync_period = 3
|
20
|
+
@websocket_path = ENV['ADMINIX_WEBSOCKET_HOST'] || DEFAULT_WEBSOCKET_HOST
|
21
|
+
@mode = 'classic'
|
22
|
+
@scripts = {
|
23
|
+
watcher_start: 'sudo systemctl start adminix.service',
|
24
|
+
watcher_stop: 'sudo systemctl stop adminix.service',
|
25
|
+
process_start: 'sudo systemctl start adminix_process.service',
|
26
|
+
process_stop: 'sudo systemctl stop adminix_process.service'
|
27
|
+
}
|
28
|
+
@watch_log_files = []
|
29
|
+
|
30
|
+
@config_store_path = "#{ENV['HOME']}/.config"
|
31
|
+
@root_path = "#{@config_store_path}/adminix"
|
32
|
+
@creds_path = "#{@root_path}/credentials"
|
33
|
+
@config_path = "#{@root_path}/config"
|
17
34
|
end
|
18
35
|
|
19
|
-
def read_creds_file
|
20
|
-
file_content = IO.read("#{ENV['HOME']}/.adminix")
|
21
|
-
data = JSON.parse(file_content) rescue nil
|
22
36
|
|
23
|
-
|
24
|
-
|
25
|
-
|
37
|
+
def read_local_config
|
38
|
+
if File.exists?(@creds_path)
|
39
|
+
content = IO.read(@creds_path)
|
40
|
+
data = JSON.parse(content) rescue {}
|
41
|
+
|
42
|
+
@service_id ||= data['service_id']
|
43
|
+
@secret_key ||= data['secret_key']
|
26
44
|
end
|
27
45
|
|
28
|
-
|
46
|
+
if File.exists?(@config_path)
|
47
|
+
content = IO.read(@config_path)
|
48
|
+
data = JSON.parse(content) rescue {}
|
49
|
+
|
50
|
+
@mode = data['mode'] || 'classic'
|
51
|
+
|
52
|
+
scripts = data['scripts'] || {}
|
53
|
+
@scripts = {
|
54
|
+
watcher_start: scripts['watcher_start'],
|
55
|
+
watcher_stop: scripts['watcher_stop'],
|
56
|
+
process_start: scripts['process_start'],
|
57
|
+
process_stop: scripts['process_stop']
|
58
|
+
}
|
59
|
+
|
60
|
+
@watch_log_files = data['watch_logs'] || []
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def export_credentials
|
65
|
+
create_config_root_if_not_exists
|
66
|
+
|
67
|
+
open(@creds_path, 'w') do |f|
|
68
|
+
f.puts(credentials.to_json)
|
69
|
+
end
|
29
70
|
end
|
30
71
|
|
31
72
|
def creds_file_exists?
|
32
|
-
File.exists?(
|
73
|
+
File.exists?(@creds_path)
|
33
74
|
end
|
34
75
|
|
35
76
|
def credentials_defined?
|
36
77
|
!service_id.nil? && !secret_key.nil?
|
37
78
|
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def credentials
|
83
|
+
{ service_id: @service_id, secret_key: @secret_key }
|
84
|
+
end
|
85
|
+
|
86
|
+
def create_config_root_if_not_exists
|
87
|
+
unless Dir.exists?(@config_store_path)
|
88
|
+
Dir.mkdir(@config_store_path)
|
89
|
+
end
|
90
|
+
|
91
|
+
unless Dir.exists?(@root_path)
|
92
|
+
Dir.mkdir(@root_path)
|
93
|
+
end
|
94
|
+
end
|
38
95
|
end
|
39
96
|
end
|
40
97
|
|
@@ -0,0 +1,23 @@
|
|
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
|
+
|
data/lib/adminix/service.rb
CHANGED
@@ -1,14 +1,18 @@
|
|
1
1
|
require 'singleton'
|
2
2
|
require 'net/http'
|
3
|
-
|
3
|
+
require 'byebug'
|
4
4
|
module Adminix
|
5
5
|
class Service
|
6
6
|
include Singleton
|
7
7
|
|
8
|
-
|
8
|
+
attr_accessor :new_logs
|
9
|
+
attr_reader :id, :process_id, :watching_logs, :syncing_logs
|
9
10
|
|
10
11
|
def initialize
|
11
12
|
@id = config.service_id
|
13
|
+
@watching_logs = []
|
14
|
+
@new_logs = false
|
15
|
+
@syncing_logs = false
|
12
16
|
end
|
13
17
|
|
14
18
|
def to_cable
|
@@ -37,6 +41,30 @@ module Adminix
|
|
37
41
|
end
|
38
42
|
end
|
39
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
|
+
|
40
68
|
def options_to_envs
|
41
69
|
data = fetch_options
|
42
70
|
|
@@ -60,7 +88,7 @@ module Adminix
|
|
60
88
|
end
|
61
89
|
|
62
90
|
def fetch_options
|
63
|
-
uri = URI.parse("#{config.host}/
|
91
|
+
uri = URI.parse("#{config.host}/v1/services/#{id}/options")
|
64
92
|
request = Net::HTTP::Get.new(uri)
|
65
93
|
request["Authorization"] = "Bearer #{config.secret_key}"
|
66
94
|
|
@@ -72,13 +100,24 @@ module Adminix
|
|
72
100
|
JSON.parse(response.body)
|
73
101
|
end
|
74
102
|
|
103
|
+
def count_logs_lines
|
104
|
+
@watching_logs = config.watch_log_files.map do |file_path|
|
105
|
+
{ lines: file_lines_number(file_path), path: file_path }
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
75
109
|
def restart!
|
76
110
|
stop!
|
77
111
|
end
|
78
112
|
|
79
113
|
def stop!
|
80
114
|
system.log "Stopping process"
|
81
|
-
|
115
|
+
case config.mode
|
116
|
+
when 'classic'
|
117
|
+
system.eval("#{config.scripts[:watcher_stop]} && #{config.scripts[:watcher_start]}")
|
118
|
+
when 'docker'
|
119
|
+
Process.kill('INT', 1) rescue nil
|
120
|
+
end
|
82
121
|
end
|
83
122
|
|
84
123
|
private
|
@@ -91,6 +130,10 @@ module Adminix
|
|
91
130
|
System.instance
|
92
131
|
end
|
93
132
|
|
133
|
+
def file_lines_number(file_path)
|
134
|
+
`wc -l #{file_path}`.to_i
|
135
|
+
end
|
136
|
+
|
94
137
|
def execute_command(key, process_id, args)
|
95
138
|
command = config.commands.find { |c| c['key'] == key }
|
96
139
|
script = command['command'].dup
|
data/lib/adminix/setup/routes.rb
CHANGED
@@ -85,6 +85,10 @@ module Adminix::Setup
|
|
85
85
|
secret_key = Services.get_secret_key(params[:t])
|
86
86
|
if id_is_valid && !secret_key.nil?
|
87
87
|
Services.import_settings(secret_key, params[:id])
|
88
|
+
Thread.start do
|
89
|
+
sleep(2)
|
90
|
+
Adminix::Service.instance.restart!
|
91
|
+
end
|
88
92
|
render('complete')
|
89
93
|
else
|
90
94
|
render('error')
|
@@ -101,7 +105,7 @@ module Adminix::Setup
|
|
101
105
|
end
|
102
106
|
|
103
107
|
set :bind, '0.0.0.0'
|
104
|
-
set :port, Adminix::Config
|
108
|
+
set :port, Adminix::Config::DEFAULT_SETUP_SERVER_PORT
|
105
109
|
|
106
110
|
run!
|
107
111
|
end
|
@@ -127,10 +127,11 @@ module Adminix::Setup
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def self.import_settings(secret_key, service_id)
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
130
|
+
config = Adminix::Config.instance
|
131
|
+
config.service_id = service_id
|
132
|
+
config.secret_key = secret_key
|
133
|
+
config.export_credentials
|
134
|
+
|
134
135
|
true
|
135
136
|
end
|
136
137
|
end
|
data/lib/adminix/version.rb
CHANGED
data/lib/adminix/watcher.rb
CHANGED
@@ -13,30 +13,41 @@ module Adminix
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
SYNC_PERIOD = 5.freeze
|
17
|
-
DEFAULT_WEBSOCKET_HOST = 'wss://api.adminix.io/websocket'.freeze
|
18
16
|
SERVICE_CHANNEL = 'ServiceChannel'.freeze
|
19
17
|
|
20
18
|
def initialize(opts)
|
19
|
+
@sync_period = config.watcher_sync_period
|
21
20
|
@pid_full = '/tmp/adminix.pid'
|
22
21
|
@service = Service.instance
|
23
22
|
|
24
23
|
@ws_client = nil
|
25
|
-
|
26
|
-
@ws_uri = "#{ws_path}?secret_key=#{config.secret_key}"
|
24
|
+
@ws_uri = "#{config.websocket_path}?secret_key=#{config.secret_key}"
|
27
25
|
@ws_channel = { channel: 'ServiceChannel', service_id: @service.id }
|
26
|
+
@ws_logs_channel = { channel: 'LogsChannel', service_id: @service.id }
|
27
|
+
|
28
|
+
@watching_files = []
|
29
|
+
|
30
|
+
if EM.epoll?
|
31
|
+
EM.epoll
|
32
|
+
elsif EM.kqueue?
|
33
|
+
EM.kqueue
|
34
|
+
else
|
35
|
+
Kernel.warn('Neither epoll nor kqueue are supported.')
|
36
|
+
end
|
28
37
|
end
|
29
38
|
|
30
39
|
def run!
|
31
40
|
trap_signal
|
32
|
-
|
41
|
+
|
42
|
+
Adminix::Service.instance.count_logs_lines
|
43
|
+
|
33
44
|
EventMachine.run do
|
34
45
|
@ws_client = ActionCableClient.new(@ws_uri, @ws_channel)
|
35
46
|
@ws_client.connected do |msg|
|
36
|
-
puts '
|
47
|
+
puts 'Service connection established'
|
37
48
|
end
|
38
49
|
@ws_client.disconnected do
|
39
|
-
system.log '
|
50
|
+
system.log 'Service disconnected. Reconnecting...'
|
40
51
|
sleep(2)
|
41
52
|
@ws_client.connect!
|
42
53
|
end
|
@@ -48,9 +59,30 @@ module Adminix
|
|
48
59
|
end
|
49
60
|
end
|
50
61
|
|
51
|
-
|
62
|
+
@ws_logs_client = ActionCableClient.new(@ws_uri, @ws_logs_channel)
|
63
|
+
@ws_logs_client.connected do |msg|
|
64
|
+
puts 'Logs connection established'
|
65
|
+
end
|
66
|
+
@ws_logs_client.disconnected do
|
67
|
+
system.log 'Logs disconnected. Reconnecting...'
|
68
|
+
sleep(2)
|
69
|
+
@ws_logs_client.connect!
|
70
|
+
end
|
71
|
+
@ws_logs_client.received { |msg| }
|
72
|
+
|
73
|
+
# Sync watcher
|
74
|
+
EventMachine.add_periodic_timer(config.watcher_sync_period) do
|
52
75
|
@ws_client.perform(:sync, @service.to_cable) if @ws_client.subscribed?
|
53
76
|
end
|
77
|
+
|
78
|
+
# Logs watcher
|
79
|
+
config.watch_log_files.each do |file_path|
|
80
|
+
EventMachine.watch_file(file_path, Adminix::LogWatchHandler)
|
81
|
+
end
|
82
|
+
|
83
|
+
EventMachine.add_periodic_timer(config.logs_sync_period) do
|
84
|
+
Adminix::Service.instance.sync_logs(@ws_logs_client)
|
85
|
+
end
|
54
86
|
end
|
55
87
|
end
|
56
88
|
|
data/lib/adminix.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adminix
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.25
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christian Dyl
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: eventmachine
|
@@ -157,6 +157,7 @@ files:
|
|
157
157
|
- lib/adminix.rb
|
158
158
|
- lib/adminix/.service.rb.swn
|
159
159
|
- lib/adminix/config.rb
|
160
|
+
- lib/adminix/log_watch_handler.rb
|
160
161
|
- lib/adminix/service.rb
|
161
162
|
- lib/adminix/setup.rb
|
162
163
|
- lib/adminix/setup/routes.rb
|